home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / misc2.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  93KB  |  3,676 lines

  1. /*
  2.  * misc2.c: misc code for maintaining the dungeon, printing player info 
  3.  *
  4.  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke 
  5.  *
  6.  * This software may be copied and distributed for educational, research, and
  7.  * not for profit purposes provided that this copyright and statement are
  8.  * included in all such copies. 
  9.  */
  10.  
  11. #include "monster.h"
  12.  
  13. /* include before constant.h because param.h defines NULL incorrectly */
  14. #ifndef USG
  15. #include <sys/types.h>
  16. #include <sys/param.h>
  17. #endif
  18.  
  19. #include "constant.h"
  20. #include "config.h"
  21. #include "types.h"
  22. #include "externs.h"
  23.  
  24. #include <ctype.h>
  25.  
  26. #ifdef USG
  27. #ifndef ATARIST_MWC
  28. #include <string.h>
  29. #else
  30. char               *index();
  31. #endif
  32. #else
  33. #include <strings.h>
  34. #endif
  35.  
  36. /* Lets do all prototypes correctly.... -CWS */
  37. #ifndef NO_LINT_ARGS
  38. #ifdef __STDC__
  39. static void prt_lnum(const char *, int32, int, int);
  40. static void prt_num(const char *, int, int, int);
  41. static void prt_long(int32, int, int);
  42. static void prt_int(int, int, int);
  43. #else
  44. static void prt_lnum();
  45. static void prt_num();
  46. static void prt_long();
  47. static void prt_int();
  48. #endif
  49. static void gain_level();
  50. #endif
  51.  
  52. static const char *stat_names[] = { "STR: ", "INT: ", "WIS: ",
  53.                     "DEX: ", "CON: ", "CHR: "};
  54.  
  55. #define BLANK_LENGTH    24
  56. static char blank_string[] = "                        ";
  57.  
  58. extern int rating;
  59.  
  60. /* Places a particular trap at location y, x        -RAK-     */
  61. void 
  62. place_trap(y, x, subval)
  63. int y, x, subval;
  64. {
  65.     register int cur_pos;
  66.  
  67.     if (!in_bounds(y, x))
  68.     return;           /* abort! -CFT */
  69.     if (cave[y][x].cptr >= MIN_MONIX)
  70.     return;           /* don't put rubble under monsters, it's annoying -CFT */
  71.  
  72.     if (cave[y][x].tptr != 0)
  73.     if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
  74.         (t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
  75.         (t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
  76.         ((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
  77.          (t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
  78.          (t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
  79.         return;           /* don't replace stairs, stores, artifacts */
  80.     else
  81.         delete_object(y, x);
  82.     cur_pos = popt();
  83.     cave[y][x].tptr = cur_pos;
  84.     invcopy(&t_list[cur_pos], OBJ_TRAP_LIST + subval);
  85. }
  86.  
  87.  
  88. /* Places rubble at location y, x            -RAK-     */
  89. void 
  90. place_rubble(y, x)
  91. int y, x;
  92. {
  93.     register int        cur_pos;
  94.     register cave_type *cave_ptr;
  95.  
  96.     if (!in_bounds(y, x))
  97.     return;               /* abort! -CFT */
  98.     if (cave[y][x].tptr != 0)
  99.     if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
  100.         (t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
  101.         (t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
  102.         ((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
  103.          (t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
  104.          (t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
  105.         return;           /* don't replace stairs, stores, artifacts */
  106.     else
  107.         delete_object(y, x);
  108.     cur_pos = popt();
  109.     cave_ptr = &cave[y][x];
  110.     cave_ptr->tptr = cur_pos;
  111.     cave_ptr->fval = BLOCKED_FLOOR;
  112.     invcopy(&t_list[cur_pos], OBJ_RUBBLE);
  113. }
  114.  
  115. /* if killed a 'Creeping _xxx_ coins'... -CWS */
  116. void
  117. get_coin_type(c_ptr)
  118. creature_type *c_ptr;
  119. {
  120.     if (!stricmp(c_ptr->name, "Creeping copper coins")) {
  121.     coin_type = 2;
  122.     }
  123.  
  124.     if (!stricmp(c_ptr->name, "Creeping silver coins")) {
  125.     coin_type = 5;
  126.     }
  127.  
  128.     if (!stricmp(c_ptr->name, "Creeping gold coins")) {
  129.     coin_type = 10;
  130.     }
  131.  
  132.     if (!stricmp(c_ptr->name, "Creeping mithril coins")) {
  133.     coin_type = 16;
  134.     }
  135.  
  136.     if (!stricmp(c_ptr->name, "Creeping adamantite coins")) {
  137.     coin_type = 17;
  138.     }
  139. }
  140.  
  141. /* Places a treasure (Gold or Gems) at given row, column -RAK-     */
  142. void 
  143. place_gold(y, x)
  144. int y, x;
  145. {
  146.     register int        i, cur_pos;
  147.     register inven_type *t_ptr;
  148.  
  149.     if (!in_bounds(y, x))
  150.     return;               /* abort! -CFT */
  151.     if (cave[y][x].tptr != 0)
  152.     if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
  153.         (t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
  154.         (t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
  155.         ((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
  156.          (t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
  157.          (t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
  158.         return;           /* don't replace stairs, stores, artifacts */
  159.     else
  160.         delete_object(y, x);
  161.     cur_pos = popt();
  162.     i = ((randint(object_level + 2) + 2) / 2) - 1;
  163.     if (randint(OBJ_GREAT) == 1)
  164.     i += randint(object_level + 1);
  165.     if (i >= MAX_GOLD)
  166.     i = MAX_GOLD - 1;
  167.     if (coin_type) {            /* if killed a Creeping _xxx_ coins... */
  168.     if (coin_type > MAX_GOLD - 1)
  169.         coin_type = 0;        /* safety check -CWS */
  170.     i = coin_type;
  171.     }
  172.     cave[y][x].tptr = cur_pos;
  173.     invcopy(&t_list[cur_pos], OBJ_GOLD_LIST + i);
  174.     t_ptr = &t_list[cur_pos];
  175.     t_ptr->cost += (8L * (long)randint((int)t_ptr->cost)) + randint(8);
  176.  
  177. /* average the values to make Creeping _xxx_ coins not give too great treasure drops */
  178.     if (coin_type)
  179.     t_ptr->cost = ((8L * (long)randint((int)object_list[OBJ_GOLD_LIST + i].cost))
  180.                + (t_ptr->cost)) >> 1;
  181.                       
  182.     if (cave[y][x].cptr == 1)
  183.     msg_print("You feel something roll beneath your feet.");
  184. }
  185.  
  186.  
  187. /* Returns the array number of a random object        -RAK-     */
  188. int 
  189. get_obj_num(level, good)
  190. int level, good;
  191. {
  192.     register int i, j;
  193.  
  194.     do {
  195.     if (level == 0)
  196.         i = randint(t_level[0]) - 1;
  197.     else {
  198.         if (level >= MAX_OBJ_LEVEL)
  199.         level = MAX_OBJ_LEVEL;
  200.         else if (randint(OBJ_GREAT) == 1) {
  201.         level = level * MAX_OBJ_LEVEL / randint(MAX_OBJ_LEVEL) + 1;
  202.         if (level > MAX_OBJ_LEVEL)
  203.             level = MAX_OBJ_LEVEL;
  204.         }
  205.     /*
  206.      * This code has been added to make it slightly more likely to get
  207.      * the higher level objects.    Originally a uniform distribution
  208.      * over all objects less than or equal to the dungeon level.  This
  209.      * distribution makes a level n objects occur approx 2/n% of the time
  210.      * on level n, and 1/2n are 0th level. 
  211.      */
  212.  
  213.         if (randint(2) == 1)
  214.         i = randint(t_level[level]) - 1;
  215.         else {           /* Choose three objects, pick the highest level. */
  216.         i = randint(t_level[level]) - 1;
  217.         j = randint(t_level[level]) - 1;
  218.         if (i < j)
  219.             i = j;
  220.         j = randint(t_level[level]) - 1;
  221.         if (i < j)
  222.             i = j;
  223.         j = object_list[sorted_objects[i]].level;
  224.         if (j == 0)
  225.             i = randint(t_level[0]) - 1;
  226.         else
  227.             i = randint(t_level[j] - t_level[j - 1]) - 1 + t_level[j - 1];
  228.         }
  229.     }
  230.     } while (((object_list[sorted_objects[i]].rare ?
  231.            (randint(object_list[sorted_objects[i]].rare) - 1) : 0) && !good)
  232.          || (object_list[sorted_objects[i]].rare == 255));
  233.     return (i);
  234. }
  235.  
  236.  
  237.  
  238. int 
  239. special_place_object(y, x)
  240. int y, x;
  241. {
  242.     register int cur_pos, tmp;
  243.     char         str[100];
  244.     int          done = 0;
  245.  
  246.     if (!in_bounds(y, x))
  247.     return 0;           /* abort! -CFT */
  248.     if (cave[y][x].tptr != 0)
  249.     if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
  250.         (t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
  251.         (t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
  252.         ((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
  253.          (t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
  254.          (t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
  255.         return 0;           /* don't replace stairs, stores, artifacts */
  256.     else
  257.         delete_object(y, x);
  258.     str[0] = 0;
  259.  
  260. again:
  261.     if (done > 20)
  262.     return 0;
  263.     tmp = randint(MAX_OBJECTS - (SPECIAL_OBJ - 1)) + (SPECIAL_OBJ - 1) - 1;
  264.     switch (tmp) {
  265.       case (SPECIAL_OBJ - 1):
  266.     done++;
  267.     if (randint(30) > 1)
  268.         goto again;
  269.     if (NARYA)
  270.         goto again;
  271.     if ((object_list[tmp].level - 40) > object_level)
  272.         goto again;
  273.     if ((object_list[tmp].level > object_level) && (randint(50) > 1))
  274.         goto again;
  275.     if ((wizard || peek))
  276.         sprintf(str, "Narya");
  277.     else
  278.         good_item_flag = TRUE;
  279.     NARYA = TRUE;
  280.     break;
  281.       case (SPECIAL_OBJ):
  282.     done++;
  283.     if (randint(35) > 1)
  284.         goto again;
  285.     if (NENYA)
  286.         goto again;
  287.     if ((object_list[tmp].level - 40) > object_level)
  288.         goto again;
  289.     if ((object_list[tmp].level > object_level) && (randint(60) > 1))
  290.         goto again;
  291.     if ((wizard || peek))
  292.         sprintf(str, "Nenya");
  293.     else
  294.         good_item_flag = TRUE;
  295.     NENYA = TRUE;
  296.     break;
  297.       case (SPECIAL_OBJ + 1):
  298.     done++;
  299.     if (randint(40) > 1)
  300.         goto again;
  301.     if (VILYA)
  302.         goto again;
  303.     if ((object_list[tmp].level - 40) > object_level)
  304.         goto again;
  305.     if ((object_list[tmp].level > object_level) && (randint(70) > 1))
  306.         goto again;
  307.     if ((wizard || peek))
  308.         sprintf(str, "Vilya");
  309.     else
  310.         good_item_flag = TRUE;
  311.     VILYA = TRUE;
  312.     break;
  313.       case (SPECIAL_OBJ + 2):
  314.     done++;
  315.     if (randint(60) > 1)
  316.         goto again;
  317.     if (POWER)
  318.         goto again;
  319.     if ((object_list[tmp].level - 40) > object_level)
  320.         goto again;
  321.     if ((object_list[tmp].level > object_level) && (randint(100) > 1))
  322.         goto again;
  323.     if ((wizard || peek))
  324.         sprintf(str, "Power (The One Ring)");
  325.     else
  326.         good_item_flag = TRUE;
  327.     POWER = TRUE;
  328.     break;
  329.       case (SPECIAL_OBJ + 3):
  330.     done++;
  331.     if (PHIAL)
  332.         goto again;
  333.     if ((object_list[tmp].level - 40) > object_level)
  334.         goto again;
  335.     if ((object_list[tmp].level > object_level) && (randint(30) > 1))
  336.         goto again;
  337.     if ((wizard || peek))
  338.         sprintf(str, "Phial of Galadriel");
  339.     else
  340.         good_item_flag = TRUE;
  341.     PHIAL = TRUE;
  342.     break;
  343.       case (SPECIAL_OBJ + 4):
  344.     done++;
  345.     if (randint(10) > 1)
  346.         goto again;
  347.     if (INGWE)
  348.         goto again;
  349.     if ((object_list[tmp].level - 40) > object_level)
  350.         goto again;
  351.     if ((object_list[tmp].level > object_level) && (randint(50) > 1))
  352.         goto again;
  353.     if ((wizard || peek))
  354.         sprintf(str, "Amulet of Ingwe");
  355.     else
  356.         good_item_flag = TRUE;
  357.     INGWE = TRUE;
  358.     break;
  359.       case (SPECIAL_OBJ + 5):
  360.     done++;
  361.     if (randint(6) > 1)
  362.         goto again;
  363.     if (CARLAMMAS)
  364.         goto again;
  365.     if ((object_list[tmp].level - 40) > object_level)
  366.         goto again;
  367.     if ((object_list[tmp].level > object_level) && (randint(35) > 1))
  368.         goto again;
  369.     if ((wizard || peek))
  370.         sprintf(str, "Amulet of Carlammas");
  371.     else
  372.         good_item_flag = TRUE;
  373.     CARLAMMAS = TRUE;
  374.     break;
  375.       case (SPECIAL_OBJ + 6):
  376.     done++;
  377.     if (randint(8) > 1)
  378.         goto again;
  379.     if (ELENDIL)
  380.         goto again;
  381.     if ((object_list[tmp].level - 40) > object_level)
  382.         goto again;
  383.     if ((object_list[tmp].level > object_level) && (randint(30) > 1))
  384.         goto again;
  385.     if ((wizard || peek))
  386.         sprintf(str, "Star of Elendil");
  387.     else
  388.         good_item_flag = TRUE;
  389.     ELENDIL = TRUE;
  390.     break;
  391.       case (SPECIAL_OBJ + 7):
  392.     done++;
  393.     if (randint(18) > 1)
  394.         goto again;
  395.     if (THRAIN)
  396.         goto again;
  397.     if ((object_list[tmp].level - 40) > object_level)
  398.         goto again;
  399.     if ((object_list[tmp].level > object_level) && (randint(60) > 1))
  400.         goto again;
  401.     if ((wizard || peek))
  402.         sprintf(str, "Arkenstone of Thrain");
  403.     else
  404.         good_item_flag = TRUE;
  405.     THRAIN = TRUE;
  406.     break;
  407.       case (SPECIAL_OBJ + 8):
  408.     done++;
  409.     if (randint(25) > 1)
  410.         goto again;
  411.     if (TULKAS)
  412.         goto again;
  413.     if ((object_list[tmp].level - 40) > object_level)
  414.         goto again;
  415.     if ((object_list[tmp].level > object_level) && (randint(65) > 1))
  416.         goto again;
  417.     if ((wizard || peek))
  418.         sprintf(str, "Ring of Tulkas");
  419.     else
  420.         good_item_flag = TRUE;
  421.     TULKAS = TRUE;
  422.     break;
  423.       case (SPECIAL_OBJ + 9):
  424.     done++;
  425.     if (randint(25) > 1)
  426.         goto again;
  427.     if (NECKLACE)
  428.         goto again;
  429.     if ((object_list[tmp].level - 40) > object_level)
  430.         goto again;
  431.     if ((object_list[tmp].level > object_level) && (randint(60) > 1))
  432.         goto again;
  433.     if ((wizard || peek))
  434.         sprintf(str, "Necklace of the Dwarves");
  435.     else
  436.         good_item_flag = TRUE;
  437.     NECKLACE = TRUE;
  438.     break;
  439.       case (SPECIAL_OBJ + 10):
  440.     done++;
  441.     if (randint(20) > 1)
  442.         goto again;
  443.     if (BARAHIR)
  444.         goto again;
  445.     if ((object_list[tmp].level - 40) > object_level)
  446.         goto again;
  447.     if ((object_list[tmp].level > object_level) && (randint(50) > 1))
  448.         goto again;
  449.     if ((wizard || peek))
  450.         sprintf(str, "Ring of Barahir");
  451.     else
  452.         good_item_flag = TRUE;
  453.     BARAHIR = TRUE;
  454.     break;
  455.     }
  456.     if (strlen(str) > 0 && (wizard || peek))
  457.     msg_print(str);
  458.     cur_pos = popt();
  459.     cave[y][x].tptr = cur_pos;
  460.     invcopy(&t_list[cur_pos], tmp);
  461.     t_list[cur_pos].timeout = 0;
  462.     t_list[cur_pos].ident |= ID_NOSHOW_TYPE; /* don't show (+x of yyy) for these */
  463.     if (object_list[tmp].level > object_level) {
  464.     rating += 2 * (object_list[sorted_objects[tmp]].level - object_level);
  465.     }
  466.     if (cave[y][x].cptr == 1)
  467.     msg_print("You feel something roll beneath your feet.");
  468.     return (-1);
  469. }
  470.  
  471. /* Places an object at given row, column co-ordinate    -RAK-   */
  472. void
  473. place_object(y, x)
  474. int y, x;
  475. {
  476.     register int cur_pos, tmp;
  477.  
  478.     if (!in_bounds(y,x)) return; /* abort! -CFT */
  479.     if (cave[y][x].tptr != 0)
  480.     if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
  481.         (t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
  482.         (t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
  483.         ((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
  484.          (t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
  485.          (t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
  486.         return; /* don't replace stairs, stores, artifacts */
  487.     else
  488.         delete_object(y,x);
  489.     
  490.     if (randint(MAX_OBJECTS)>SPECIAL_OBJ && randint(10)==1)
  491.     if (special_place_object(y,x)==(-1))
  492.         return;
  493.     cur_pos = popt();
  494.     cave[y][x].tptr = cur_pos;
  495.  
  496.     do {       /* don't generate another chest if opening_chest is true -CWS */
  497.     tmp = get_obj_num(dun_level, FALSE);
  498.     } while (opening_chest && (object_list[sorted_objects[tmp]].tval == TV_CHEST));
  499.     
  500.     invcopy(&t_list[cur_pos], sorted_objects[tmp]);
  501.     magic_treasure(cur_pos, dun_level, FALSE, 0);
  502.     if (object_list[sorted_objects[tmp]].level > dun_level)
  503.     rating += object_list[sorted_objects[tmp]].level - dun_level;
  504.     if (peek) {
  505.     if (object_list[sorted_objects[tmp]].level > dun_level) {
  506.         char buf[200];
  507.         int8u temp;
  508.         
  509.         temp=t_list[cur_pos].ident;
  510.         t_list[cur_pos].ident |= ID_STOREBOUGHT;
  511.         objdes(buf, &t_list[cur_pos], TRUE);
  512.         t_list[cur_pos].ident = temp;
  513.         msg_print(buf);
  514.     }
  515.     }
  516.     if (cave[y][x].cptr == 1)
  517.     msg_print ("You feel something roll beneath your feet.");
  518. }
  519.  
  520. /* Places a GOOD-object at given row, column co-ordinate ~Ludwig */
  521. void 
  522. place_special(y, x, good)
  523. int    y, x;
  524. int32u good;
  525. {
  526.     register int cur_pos, tmp;
  527.     int          tv, is_good = FALSE;
  528.  
  529.     if (!in_bounds(y, x))
  530.     return;               /* abort! -CFT */
  531.     if (cave[y][x].tptr != 0)
  532.     if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
  533.         (t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
  534.         (t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
  535.         ((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
  536.          (t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
  537.          (t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
  538.         return;           /* don't replace stairs, stores, artifacts */
  539.     else
  540.         delete_object(y, x);
  541.  
  542.     if (randint(10) == 1)
  543.     if (special_place_object(y, x) == (-1))
  544.         return;
  545.     cur_pos = popt();
  546.     cave[y][x].tptr = cur_pos;
  547.     do {
  548.     tmp = get_obj_num((object_level + 10), TRUE);
  549.     tv = object_list[sorted_objects[tmp]].tval;
  550.     if ((tv == TV_HELM) || (tv == TV_SHIELD) ||
  551.         (tv == TV_CLOAK) || (tv == TV_HAFTED) || (tv == TV_POLEARM) ||
  552.         (tv == TV_BOW) || (tv == TV_BOLT) || (tv == TV_ARROW) ||
  553.         (tv == TV_BOOTS) || (tv == TV_GLOVES))
  554.         is_good = TRUE;
  555.     if ((tv == TV_SWORD) &&
  556.         strncmp("& Broken", object_list[sorted_objects[tmp]].name, 8))
  557.         is_good = TRUE;       /* broken swords/daggers are NOT good!
  558.                     * -CFT */
  559.     if ((tv == TV_HARD_ARMOR) &&
  560.         strncmp("Rusty", object_list[sorted_objects[tmp]].name, 5))
  561.         is_good = TRUE;       /* rusty chainmail is NOT good! -CFT */
  562.     if ((tv == TV_SOFT_ARMOR) &&
  563.      stricmp("some filthy rags", object_list[sorted_objects[tmp]].name))
  564.         is_good = TRUE;       /* nor are rags! -CFT */
  565.     if ((tv == TV_MAGIC_BOOK) &&    /* if book, good must be one of the
  566.                      * deeper, special must be Raal's */
  567.         (object_list[sorted_objects[tmp]].subval > ((good & SPECIAL) ? 71 : 67)))
  568.         is_good = TRUE;
  569.     if ((tv == TV_PRAYER_BOOK) &&    /* if book, good must be one of the
  570.                      * deeper, special must be Wrath of
  571.                      * God */
  572.         (object_list[sorted_objects[tmp]].subval > ((good & SPECIAL) ? 71 : 67)))
  573.         is_good = TRUE;
  574.     } while (!is_good);
  575.     invcopy(&t_list[cur_pos], sorted_objects[tmp]);
  576.     magic_treasure(cur_pos, object_level, (good & SPECIAL) ? 666 : 1, 0);
  577.     if (peek) {
  578.     if (object_list[sorted_objects[tmp]].level > object_level) {
  579.         char                buf[200];
  580.         int8u               t;
  581.  
  582.         t = t_list[cur_pos].ident;
  583.         t_list[cur_pos].ident |= ID_STOREBOUGHT;
  584.         objdes(buf, &t_list[cur_pos], TRUE);
  585.         t_list[cur_pos].ident = t;
  586.         msg_print(buf);
  587.     }
  588.     }
  589.     if (cave[y][x].cptr == 1)
  590.     msg_print("You feel something roll beneath your feet.");
  591. }
  592.  
  593.  
  594. /* Allocates an object for tunnels and rooms        -RAK-     */
  595. void 
  596. alloc_object(alloc_set, typ, num)
  597. int (*alloc_set) ();
  598. int typ, num;
  599. {
  600.     register int i, j, k;
  601.  
  602.     for (k = 0; k < num; k++) {
  603.     do {
  604.         i = randint(cur_height) - 1;
  605.         j = randint(cur_width) - 1;
  606.     }
  607.     /*
  608.      * don't put an object beneath the player, this could cause problems if
  609.      * player is standing under rubble, or on a trap 
  610.      */
  611.     while ((!(*alloc_set) (cave[i][j].fval)) ||
  612.            (cave[i][j].tptr != 0) || (i == char_row && j == char_col));
  613.     if (typ < 4) {           /* typ == 2 not used, used to be visible
  614.                     * traps */
  615.         if (typ == 1)
  616.         place_trap(i, j, randint(MAX_TRAP) - 1);    /* typ == 1 */
  617.         else
  618.         place_rubble(i, j);/* typ == 3 */
  619.     } else {
  620.         object_level = dun_level;
  621.         if (typ == 4)
  622.         place_gold(i, j);  /* typ == 4 */
  623.         else
  624.         place_object(i, j);/* typ == 5 */
  625.     }
  626.     }
  627. }
  628.  
  629.  
  630. /* Creates objects nearby the coordinates given        -RAK-     */
  631. void 
  632. random_object(y, x, num)
  633. int y, x, num;
  634. {
  635.     register int        i, j, k;
  636.     register cave_type *cave_ptr;
  637.  
  638.     do {
  639.     i = 0;
  640.     do {
  641.         do {
  642.         j = y - 3 + randint(5);
  643.         k = x - 4 + randint(7);
  644.         } while (!in_bounds(j, k));
  645.         cave_ptr = &cave[j][k];
  646.         if ((cave_ptr->fval <= MAX_CAVE_FLOOR) && (cave_ptr->tptr == 0)) {
  647.         object_level = dun_level;
  648.         if (randint(100) < 75)
  649.             place_object(j, k);
  650.         else
  651.             place_gold(j, k);
  652.         i = 9;
  653.         }
  654.         i++;
  655.     }
  656.     while (i <= 10);
  657.     num--;
  658.     }
  659.     while (num != 0);
  660. }
  661.  
  662. void 
  663. special_random_object(y, x, num)
  664. int y, x, num;
  665. {
  666.     register int        i, j, k;
  667.     register cave_type *cave_ptr;
  668.  
  669.     object_level = dun_level;
  670.     do {
  671.     i = 0;
  672.     do {
  673.         j = y - 3 + randint(5);
  674.         k = x - 4 + randint(7);
  675.         cave_ptr = &cave[j][k];
  676.         if ((cave_ptr->fval <= MAX_CAVE_FLOOR) && (cave_ptr->tptr == 0)) {
  677.         if (randint(5) == 1) {
  678.             if (!special_place_object(j, k))
  679.             place_special(j, k, SPECIAL);
  680.         } else {
  681.             place_special(j, k, SPECIAL);
  682.         }
  683.         i = 9;
  684.         }
  685.         i++;
  686.     }
  687.     while (i <= 10);
  688.     num--;
  689.     }
  690.     while (num != 0);
  691. }
  692.  
  693. /* Converts stat num into string            -RAK-     */
  694. void 
  695. cnv_stat(my_stat, out_val)
  696. int   my_stat;
  697. char *out_val;
  698. {
  699.     register int16u stat = my_stat;
  700.     register int    part1, part2;
  701.  
  702.     if (stat > 18) {
  703.     part1 = 18;
  704.     part2 = stat - 18;
  705.     if (part2 >= 220)
  706.         (void)sprintf(out_val, "%2d/*** ", part1);
  707.     else if (part2 >= 100)
  708.         (void)sprintf(out_val, "%2d/%03d ", part1, part2);
  709.     else
  710.         (void)sprintf(out_val, " %2d/%02d ", part1, part2);
  711.     } else
  712.     (void)sprintf(out_val, "%6d ", stat);
  713. }
  714.  
  715.  
  716. /* Print character stat in given row, column        -RAK-     */
  717. void 
  718. prt_stat(stat)
  719. int stat;
  720. {
  721.     vtype out_val1;
  722.  
  723.     cnv_stat(py.stats.use_stat[stat], out_val1);
  724.     put_buffer(stat_names[stat], 5 + stat, STAT_COLUMN);
  725.     put_buffer(out_val1, 5 + stat, STAT_COLUMN + 6);
  726. }
  727.  
  728.  
  729. /* Print character info in given row, column        -RAK-     */
  730. /* the longest title is 13 characters, so only pad to 13 */
  731. void 
  732. prt_field(info, row, column)
  733. const char *info;
  734. int         row, column;
  735. {
  736.     put_buffer(&blank_string[BLANK_LENGTH - 13], row, column);
  737.     put_buffer(info, row, column);
  738. }
  739.  
  740. /* Print long number with header at given row, column */
  741. static void 
  742. prt_lnum(header, num, row, column)
  743. const char *header;
  744. int32       num;
  745. int         row, column;
  746. {
  747.     vtype out_val;
  748.  
  749.     (void)sprintf(out_val, "%s%9ld", header, (long)num);
  750.     put_buffer(out_val, row, column);
  751. }
  752.  
  753. /* Print number with header at given row, column    -RAK-     */
  754. static void 
  755. prt_num(header, num, row, column)
  756. const char *header;
  757. int         num, row, column;
  758. {
  759.     vtype out_val;
  760.  
  761.     (void)sprintf(out_val, "%s   %6d", header, num);
  762.     put_buffer(out_val, row, column);
  763. }
  764.  
  765. /* Print long number at given row, column */
  766. static void 
  767. prt_long(num, row, column)
  768. int32 num;
  769. int   row, column;
  770. {
  771.     vtype out_val;
  772.  
  773.     (void)sprintf(out_val, "%9ld", (long)num);
  774.     put_buffer(out_val, row, column);
  775. }
  776.  
  777. /* Print number at given row, column    -RAK-     */
  778. static void 
  779. prt_int(num, row, column)
  780.     int num, row, column;
  781. {
  782.     vtype out_val;
  783.  
  784.     (void)sprintf(out_val, "%6d", num);
  785.     put_buffer(out_val, row, column);
  786. }
  787.  
  788.  
  789. /* Adjustment for wisdom/intelligence                -JWT-     */
  790. int 
  791. stat_adj(stat)
  792.     int stat;
  793. {
  794.     register int value;
  795.  
  796.     value = py.stats.use_stat[stat];
  797.     if (value > 228)
  798.     return (20);
  799.     else if (value > 218)
  800.     return (18);
  801.     else if (value > 198)
  802.     return (16);
  803.     else if (value > 188)
  804.     return (15);
  805.     else if (value > 178)
  806.     return (14);
  807.     else if (value > 168)
  808.     return (13);
  809.     else if (value > 158)
  810.     return (12);
  811.     else if (value > 148)
  812.     return (11);
  813.     else if (value > 138)
  814.     return (10);
  815.     else if (value > 128)
  816.     return (9);
  817.     else if (value > 118)
  818.     return (8);
  819.     else if (value == 118)
  820.     return (7);
  821.     else if (value > 107)
  822.     return (6);
  823.     else if (value > 87)
  824.     return (5);
  825.     else if (value > 67)
  826.     return (4);
  827.     else if (value > 17)
  828.     return (3);
  829.     else if (value > 14)
  830.     return (2);
  831.     else if (value > 7)
  832.     return (1);
  833.     else
  834.     return (0);
  835. }
  836.  
  837.  
  838. /* Adjustment for charisma                -RAK-     */
  839. /* Percent decrease or increase in price of goods         */
  840. int 
  841. chr_adj()
  842. {
  843.     register int charisma;
  844.  
  845.     charisma = py.stats.use_stat[A_CHR];
  846.     if (charisma > 217)
  847.     return (80);
  848.     else if (charisma > 187)
  849.     return (86);
  850.     else if (charisma > 147)
  851.     return (88);
  852.     else if (charisma > 117)
  853.     return (90);
  854.     else if (charisma > 107)
  855.     return (92);
  856.     else if (charisma > 87)
  857.     return (94);
  858.     else if (charisma > 67)
  859.     return (96);
  860.     else if (charisma > 18)
  861.     return (98);
  862.     else
  863.     switch (charisma) {
  864.       case 18:
  865.         return (100);
  866.       case 17:
  867.         return (101);
  868.       case 16:
  869.         return (102);
  870.       case 15:
  871.         return (103);
  872.       case 14:
  873.         return (104);
  874.       case 13:
  875.         return (106);
  876.       case 12:
  877.         return (108);
  878.       case 11:
  879.         return (110);
  880.       case 10:
  881.         return (112);
  882.       case 9:
  883.         return (114);
  884.       case 8:
  885.         return (116);
  886.       case 7:
  887.         return (118);
  888.       case 6:
  889.         return (120);
  890.       case 5:
  891.         return (122);
  892.       case 4:
  893.         return (125);
  894.       case 3:
  895.         return (130);
  896.       default:
  897.         return (140);
  898.     }
  899. }
  900.  
  901.  
  902. /* Returns a character's adjustment to hit points     -JWT-     */
  903. int 
  904. con_adj()
  905. {
  906.     register int con;
  907.  
  908.     con = py.stats.use_stat[A_CON];
  909.     if (con < 7)
  910.     return (con - 7);
  911.     else if (con < 17)
  912.     return (0);
  913.     else if (con == 17)
  914.     return (1);
  915.     else if (con < 94)
  916.     return (2);
  917.     else if (con < 117)
  918.     return (3);
  919.     else if (con < 119)
  920.     return (4);
  921.     else if (con < 128)
  922.     return (5);
  923.     else if (con < 138)
  924.     return (6);
  925.     else if (con < 158)
  926.     return (7);
  927.     else if (con < 168)
  928.     return (8);
  929.     else if (con < 178)
  930.     return (9);
  931.     else if (con < 188)
  932.     return (10);
  933.     else if (con < 198)
  934.     return (11);
  935.     else if (con < 208)
  936.     return (12);
  937.     else if (con < 228)
  938.     return (13);
  939.     else
  940.     return (14);
  941. }
  942.  
  943.  
  944. const char *
  945. title_string()
  946. {
  947.     const char *p;
  948.  
  949.     if (py.misc.lev < 1)
  950.     p = "Babe in arms";
  951.     else if (py.misc.lev <= MAX_PLAYER_LEVEL)
  952.     p = player_title[py.misc.pclass][py.misc.lev - 1];
  953.     else if (py.misc.male)
  954.     p = "**KING**";
  955.     else
  956.     p = "**QUEEN**";
  957.     return p;
  958. }
  959.  
  960.  
  961. /* Prints title of character                -RAK-     */
  962. void 
  963. prt_title()
  964. {
  965.     prt_field(title_string(), 3, STAT_COLUMN);
  966. }
  967.  
  968.  
  969. /* Prints level                        -RAK-     */
  970. void 
  971. prt_level()
  972. {
  973.     prt_int((int)py.misc.lev, 12, STAT_COLUMN + 6);
  974. }
  975.  
  976.  
  977. /* Prints players current mana points.         -RAK-     */
  978. void 
  979. prt_cmana()
  980. {
  981.     prt_int(py.misc.cmana, 14, STAT_COLUMN + 6);
  982. }
  983.  
  984.  
  985. /* Prints Max hit points                -RAK-     */
  986. void 
  987. prt_mhp()
  988. {
  989.     prt_int(py.misc.mhp, 15, STAT_COLUMN + 6);
  990. }
  991.  
  992.  
  993. /* Prints players current hit points            -RAK-     */
  994. void 
  995. prt_chp()
  996. {
  997.     prt_int(py.misc.chp, 16, STAT_COLUMN + 6);
  998. }
  999.  
  1000.  
  1001. /* prints current AC                    -RAK-     */
  1002. void 
  1003. prt_pac()
  1004. {
  1005.     prt_int(py.misc.dis_ac, 18, STAT_COLUMN + 6);
  1006. }
  1007.  
  1008.  
  1009. /* Prints current gold                    -RAK-     */
  1010. void 
  1011. prt_gold()
  1012. {
  1013.     prt_long(py.misc.au, 19, STAT_COLUMN + 3);
  1014. }
  1015.  
  1016.  
  1017. /* Prints depth in stat area                -RAK-     */
  1018. void 
  1019. prt_depth()
  1020. {
  1021.     vtype               depths;
  1022.     register int        depth;
  1023.  
  1024.     depth = dun_level * 50;
  1025.     if (depth == 0)
  1026.     (void)strcpy(depths, "Town    ");
  1027.     else
  1028.     (void)sprintf(depths, "%d ft", depth);
  1029.     prt(depths, 23, 70);
  1030. }
  1031.  
  1032.  
  1033. /* Prints status of hunger                -RAK-     */
  1034. void 
  1035. prt_hunger()
  1036. {
  1037.     if (PY_WEAK & py.flags.status)
  1038.     put_buffer("Weak  ", 23, 0);
  1039.     else if (PY_HUNGRY & py.flags.status)
  1040.     put_buffer("Hungry", 23, 0);
  1041.     else
  1042.     put_buffer("      ", 23, 0);
  1043. }
  1044.  
  1045.  
  1046. /* Prints Blind status                    -RAK-     */
  1047. void 
  1048. prt_blind()
  1049. {
  1050.     if (PY_BLIND & py.flags.status)
  1051.     put_buffer("Blind", 23, 7);
  1052.     else
  1053.     put_buffer("     ", 23, 7);
  1054. }
  1055.  
  1056.  
  1057. /* Prints Confusion status                -RAK-     */
  1058. void 
  1059. prt_confused()
  1060. {
  1061.     if (PY_CONFUSED & py.flags.status)
  1062.     put_buffer("Confused", 23, 13);
  1063.     else
  1064.     put_buffer("        ", 23, 13);
  1065. }
  1066.  
  1067.  
  1068. /* Prints Fear status                    -RAK-     */
  1069. void 
  1070. prt_afraid()
  1071. {
  1072.     if (PY_FEAR & py.flags.status)
  1073.     put_buffer("Afraid", 23, 22);
  1074.     else
  1075.     put_buffer("      ", 23, 22);
  1076. }
  1077.  
  1078.  
  1079. /* Prints Poisoned status                -RAK-     */
  1080. void 
  1081. prt_poisoned()
  1082. {
  1083.     if (PY_POISONED & py.flags.status)
  1084.     put_buffer("Poisoned", 23, 29);
  1085.     else
  1086.     put_buffer("        ", 23, 29);
  1087. }
  1088.  
  1089.  
  1090. /* Prints Searching, Resting, Paralysis, or 'count' status    -RAK-     */
  1091. void 
  1092. prt_state()
  1093. {
  1094.     char tmp[16];
  1095.  
  1096.     py.flags.status &= ~PY_REPEAT;
  1097.     if (py.flags.paralysis > 1)
  1098.     put_buffer("Paralysed ", 23, 38);
  1099.     else if (PY_REST & py.flags.status) {
  1100.     if (py.flags.rest > 0)
  1101.         (void)sprintf(tmp, "Rest %-5d", py.flags.rest);
  1102.     else if (py.flags.rest == -1)
  1103.         (void)sprintf(tmp, "Rest *****");
  1104.     else if (py.flags.rest == -2)
  1105.         (void)sprintf(tmp, "Rest &&&&&");
  1106.     put_buffer(tmp, 23, 38);
  1107.     } else if (command_count > 0) {
  1108.     (void)sprintf(tmp, "Repeat %-3d", command_count);
  1109.     py.flags.status |= PY_REPEAT;
  1110.     put_buffer(tmp, 23, 38);
  1111.     if (PY_SEARCH & py.flags.status)
  1112.         put_buffer("Search    ", 23, 38);
  1113.     } else if (PY_SEARCH & py.flags.status)
  1114.     put_buffer("Searching ", 23, 38);
  1115.     else               /* "repeat 999" is 10 characters */
  1116.     put_buffer("          ", 23, 38);
  1117. }
  1118.  
  1119.  
  1120. /* Prints the speed of a character.            -CJS- */
  1121. void 
  1122. prt_speed()
  1123. {
  1124.     register int i;
  1125.  
  1126.     i = py.flags.speed;
  1127.     if (PY_SEARCH & py.flags.status)    /* Search mode. */
  1128.     i--;
  1129.     if (i > 2)
  1130.     put_buffer("Extremely Slow", 23, 49);
  1131.     else if (i == 2)
  1132.     put_buffer("Very Slow     ", 23, 49);
  1133.     else if (i == 1)
  1134.     put_buffer("Slow          ", 23, 49);
  1135.     else if (i == 0)
  1136.     put_buffer("              ", 23, 49);
  1137.     else if (i == -1)
  1138.     put_buffer("Fast          ", 23, 49);
  1139.     else if (i == -2)
  1140.     put_buffer("Very Fast     ", 23, 49);
  1141.     else if (i == -3)
  1142.     put_buffer("Extremely Fast", 23, 49);
  1143.     else if (i == -4)
  1144.     put_buffer("Deadly Speed  ", 23, 49);
  1145.     else
  1146.     put_buffer("Light Speed   ", 23, 49);
  1147. }
  1148.  
  1149.  
  1150. void 
  1151. prt_study()
  1152. {
  1153.     py.flags.status &= ~PY_STUDY;
  1154.     if (py.flags.new_spells != 0)
  1155.     put_buffer("Study", 23, 64);
  1156.     else
  1157.     put_buffer("     ", 23, 64);
  1158. }
  1159.  
  1160. void 
  1161. cut_player(c)
  1162. int c;
  1163. {
  1164.     py.flags.cut += c;
  1165.     c = py.flags.cut;
  1166.     if (c > 5000)
  1167.     msg_print("You have been given a mortal wound.");
  1168.     else if (c > 900)
  1169.     msg_print("You have been given a deep gash.");
  1170.     else if (c > 200)
  1171.     msg_print("You have been given a severe cut.");
  1172.     else if (c > 100)
  1173.     msg_print("You have been given a nasty cut.");
  1174.     else if (c > 50)
  1175.     msg_print("You have been given a bad cut.");
  1176.     else if (c > 10)
  1177.     msg_print("You have been given a light cut.");
  1178.     else if (c > 0)
  1179.     msg_print("You have been given a graze.");
  1180. }
  1181.  
  1182. void 
  1183. prt_cut()
  1184. {
  1185.     int c = py.flags.cut;
  1186.  
  1187.     if (c > 900)
  1188.     put_buffer("Mortal wound", 21, 0);
  1189.     else if (c > 300)
  1190.     put_buffer("Deep gash   ", 21, 0);
  1191.     else if (c > 200)
  1192.     put_buffer("Severe cut  ", 21, 0);
  1193.     else if (c > 45)
  1194.     put_buffer("Nasty cut   ", 21, 0);
  1195.     else if (c > 15)
  1196.     put_buffer("Bad cut     ", 21, 0);
  1197.     else if (c > 5)
  1198.     put_buffer("Light cut   ", 21, 0);
  1199.     else if (c > 0)
  1200.     put_buffer("Graze       ", 21, 0);
  1201.     else
  1202.     put_buffer("            ", 21, 0);
  1203. }
  1204.  
  1205. void 
  1206. stun_player(s)
  1207. int s;
  1208. {
  1209.     int t;
  1210.  
  1211.     if (!py.flags.sound_resist) {
  1212.     t = py.flags.stun;
  1213.     py.flags.stun += s;
  1214.     s = py.flags.stun;
  1215.     if (s > 100) {
  1216.         msg_print("You have been knocked out.");
  1217.         if (t == 0) {
  1218.         py.misc.ptohit -= 20;
  1219.         py.misc.ptodam -= 20;
  1220.         py.misc.dis_th -= 20;
  1221.         py.misc.dis_td -= 20;
  1222.         } else if (t <= 50) {
  1223.         py.misc.ptohit -= 15;
  1224.         py.misc.ptodam -= 15;
  1225.         py.misc.dis_th -= 15;
  1226.         py.misc.dis_td -= 15;
  1227.         }
  1228.     } else if (s > 50) {
  1229.         msg_print("You've been heavily stunned.");
  1230.         if (t == 0) {
  1231.         py.misc.ptohit -= 20;
  1232.         py.misc.ptodam -= 20;
  1233.         py.misc.dis_th -=20;
  1234.         py.misc.dis_td -=20;
  1235.         } else if (t <= 50) {
  1236.         py.misc.ptohit -= 15;
  1237.         py.misc.ptodam -= 15;
  1238.                 py.misc.dis_th -= 15;
  1239.                 py.misc.dis_td -= 15;
  1240.         }
  1241.     } else if (s > 0) {
  1242.         msg_print("You've been stunned.");
  1243.         if (t == 0) {
  1244.         py.misc.ptohit -= 5;
  1245.         py.misc.ptodam -= 5;
  1246.                 py.misc.dis_th -= 5;
  1247.                 py.misc.dis_td -= 5;
  1248.         }
  1249.     }
  1250.     }
  1251. }
  1252.  
  1253. void 
  1254. prt_stun()
  1255. {
  1256.     int s = py.flags.stun;
  1257.  
  1258.     if (!py.flags.sound_resist) {
  1259.     if (s > 100)
  1260.         put_buffer("Knocked out ", 22, 0);
  1261.     else if (s > 50)
  1262.         put_buffer("Heavy stun  ", 22, 0);
  1263.     else if (s > 0)
  1264.         put_buffer("Stun        ", 22, 0);
  1265.     else
  1266.         put_buffer("            ", 22, 0);
  1267.     }
  1268. }
  1269.  
  1270. /* Prints winner status on display            -RAK-     */
  1271. void 
  1272. prt_winner()
  1273. {
  1274.     if (wizard)
  1275.     put_buffer("Wizard", 20, 0);
  1276.     else if (total_winner)
  1277.     put_buffer("Winner", 20, 0);
  1278.     else
  1279.     put_buffer("       ", 20, 0);
  1280. }
  1281.  
  1282.  
  1283. int16u 
  1284. modify_stat(stat, amount)
  1285. int stat;
  1286. int amount;
  1287. {
  1288.     register int    loop, i;
  1289.     register int16u tmp_stat;
  1290.  
  1291.     tmp_stat = py.stats.cur_stat[stat];
  1292.     loop = (amount < 0 ? -amount : amount);
  1293.     for (i = 0; i < loop; i++) {
  1294.     if (amount > 0) {
  1295.         if (tmp_stat < 18)
  1296.         tmp_stat++;
  1297.         else
  1298.         tmp_stat += 10;
  1299.     } else {
  1300.         if (tmp_stat > 27)
  1301.         tmp_stat -= 10;
  1302.         else if (tmp_stat > 18)
  1303.         tmp_stat = 18;
  1304.         else if (tmp_stat > 3)
  1305.         tmp_stat--;
  1306.     }
  1307.     }
  1308.     return tmp_stat;
  1309. }
  1310.  
  1311.  
  1312. /* Set the value of the stat which is actually used.     -CJS- */
  1313. void 
  1314. set_use_stat(stat)
  1315. int stat;
  1316. {
  1317.     py.stats.use_stat[stat] = modify_stat(stat, py.stats.mod_stat[stat]);
  1318.  
  1319.     if (stat == A_STR) {
  1320.     py.flags.status |= PY_STR_WGT;
  1321.     calc_bonuses();
  1322.     } else if (stat == A_DEX)
  1323.     calc_bonuses();
  1324.     else if (stat == A_INT && class[py.misc.pclass].spell == MAGE) {
  1325.     calc_spells(A_INT);
  1326.     calc_mana(A_INT);
  1327.     } else if (stat == A_WIS && class[py.misc.pclass].spell == PRIEST) {
  1328.     calc_spells(A_WIS);
  1329.     calc_mana(A_WIS);
  1330.     } else if (stat == A_CON)
  1331.     calc_hitpoints();
  1332. }
  1333.  
  1334.  
  1335. /* Increases a stat by one randomized level        -RAK-     */
  1336. int 
  1337. inc_stat(stat)
  1338. register int stat;
  1339. {
  1340.     register int tmp_stat, gain;
  1341.  
  1342.     res_stat(stat);
  1343.     tmp_stat = py.stats.cur_stat[stat];
  1344.     if (tmp_stat < 118) {
  1345.     if (tmp_stat < 18) {       
  1346.         gain = randint(2);        /* let's be able to monitor the increase -CWS */
  1347.         tmp_stat += gain;
  1348.     } else if (tmp_stat < 116) {
  1349.     /* stat increases by 1/6 to 1/3 of difference from max */
  1350.         gain = ((118 - tmp_stat) / 2 + 3) >> 1;
  1351.         tmp_stat += randint(gain) + gain / 2;
  1352.         if (tmp_stat > 117)
  1353.         tmp_stat = 117;
  1354.     } else
  1355.         tmp_stat++;
  1356.  
  1357.     py.stats.cur_stat[stat] = tmp_stat;
  1358.     if (tmp_stat > py.stats.max_stat[stat])
  1359.         py.stats.max_stat[stat] = tmp_stat;
  1360.     set_use_stat(stat);
  1361.     prt_stat(stat);
  1362.     return TRUE;
  1363.     } else
  1364.     return FALSE;
  1365. }
  1366.  
  1367.  
  1368. /* Decreases a stat by one randomized level        -RAK-     */
  1369. int 
  1370. dec_stat(stat)
  1371. register int stat;
  1372. {
  1373.     register int tmp_stat, loss;
  1374.  
  1375.     tmp_stat = py.stats.cur_stat[stat];
  1376.     if (tmp_stat > 3) {
  1377.     if (tmp_stat < 19)
  1378.         tmp_stat--;
  1379.     else if (tmp_stat < 117) {
  1380.         loss = (((118 - tmp_stat) >> 1) + 1) >> 1;
  1381.         tmp_stat += -randint(loss) - loss;
  1382.         if (tmp_stat < 18)
  1383.         tmp_stat = 18;
  1384.     } else
  1385.         tmp_stat--;
  1386.  
  1387.     py.stats.cur_stat[stat] = tmp_stat;
  1388.     set_use_stat(stat);
  1389.     prt_stat(stat);
  1390.     return TRUE;
  1391.     } else
  1392.     return FALSE;
  1393. }
  1394.  
  1395.  
  1396. /* Restore a stat.  Return TRUE only if this actually makes a difference. */
  1397. int 
  1398. res_stat(stat)
  1399. int stat;
  1400. {
  1401.     register int i;
  1402.  
  1403.     i = py.stats.max_stat[stat] - py.stats.cur_stat[stat];
  1404.     if (i) {
  1405.     py.stats.cur_stat[stat] += i;
  1406.     set_use_stat(stat);
  1407.     prt_stat(stat);
  1408.     return TRUE;
  1409.     }
  1410.     return FALSE;
  1411. }
  1412.  
  1413. /*
  1414.  * Boost a stat artificially (by wearing something). If the display argument
  1415.  * is TRUE, then increase is shown on the screen. 
  1416.  */
  1417. void 
  1418. bst_stat(stat, amount)
  1419. int stat, amount;
  1420. {
  1421.     py.stats.mod_stat[stat] += amount;
  1422.  
  1423.     set_use_stat(stat);
  1424. /* can not call prt_stat() here, may be in store, may be in inven_command */
  1425.     py.flags.status |= (PY_STR << stat);
  1426. }
  1427.  
  1428.  
  1429. /* Returns a character's adjustment to hit.         -JWT-     */
  1430. int 
  1431. tohit_adj()
  1432. {
  1433.     register int total, stat;
  1434.  
  1435.     stat = py.stats.use_stat[A_DEX];
  1436.     if      (stat <   4)  total = -3;
  1437.     else if (stat <   6)  total = -2;
  1438.     else if (stat <   8)  total = -1;
  1439.     else if (stat <  16)  total =  0;
  1440.     else if (stat <  17)  total =  1;
  1441.     else if (stat <  18)  total =  2;
  1442.     else if (stat <  69)  total =  3;
  1443.     else if (stat < 108)  total =  4; /* 18/51 to 18/89 -CFT */
  1444.     else if (stat < 118)  total =  5; /* 18/90 to 18/99 -CFT */
  1445.     else if (stat < 128)  total =  6; /* 18/100 to 18/109 -CFT */
  1446.     else if (stat < 138)  total =  7;
  1447.     else if (stat < 148)  total =  8;
  1448.     else if (stat < 158)  total =  9;
  1449.     else if (stat < 168)  total = 10;
  1450.     else if (stat < 178)  total = 11;
  1451.     else if (stat < 188)  total = 12;
  1452.     else if (stat < 198)  total = 13;
  1453.     else if (stat < 218)  total = 14;
  1454.     else if (stat < 228)  total = 15;
  1455.     else total = 17;
  1456.     stat = py.stats.use_stat[A_STR];
  1457.     if      (stat <   4)  total -= 3;
  1458.     else if (stat <   5)  total -= 2;
  1459.     else if (stat <   7)  total -= 1;
  1460.     else if (stat <  18)  total -= 0;
  1461.     else if (stat <  88)  total += 1; /* 18 to 18/69 -CFT */
  1462.     else if (stat <  98)  total += 2; /* 18/70 to 18/79 -CFT */
  1463.     else if (stat < 108)  total += 3; /* 18/80 to 18/89 -CFT */
  1464.     else if (stat < 118)  total += 4; /* 18/90 to 18/99 -CFT */
  1465.     else if (stat < 128)  total += 5; /* 18/100 to 18/109 -CFT */
  1466.     else if (stat < 138)  total += 6;
  1467.     else if (stat < 148)  total += 7;
  1468.     else if (stat < 158)  total += 8;
  1469.     else if (stat < 168)  total += 9;
  1470.     else if (stat < 178)  total +=10;
  1471.     else if (stat < 188)  total +=11;
  1472.     else if (stat < 198)  total +=12;
  1473.     else if (stat < 218)  total +=13;
  1474.     else if (stat < 228)  total +=14;
  1475.     else total += 16;
  1476.     return (total);
  1477. }
  1478.  
  1479.  
  1480. /* Returns a character's adjustment to armor class     -JWT-     */
  1481. int 
  1482. toac_adj()
  1483. {
  1484.     register int stat;
  1485.  
  1486.     stat = py.stats.use_stat[A_DEX];
  1487.     if      (stat <   4)  return(-4);
  1488.     else if (stat ==  4)  return(-3);
  1489.     else if (stat ==  5)  return(-2);
  1490.     else if (stat ==  6)  return(-1);
  1491.     else if (stat <  15)  return( 0);
  1492.     else if (stat <  18)  return( 1);
  1493.     else if (stat <  58)  return( 2); /* 18 to 18/49 -CFT */
  1494.     else if (stat <  98)  return( 3); /* 18/50 to 18/79 -CFT */
  1495.     else if (stat < 108)  return( 4); /* 18/80 to 18/89 -CFT */
  1496.     else if (stat < 118)  return( 5); /* 18/90 to /99 -CFT */
  1497.     else if (stat < 128)  return( 6); /* /100 to /109 -CFT */
  1498.     else if (stat < 138)  return( 7);
  1499.     else if (stat < 148)  return( 8);
  1500.     else if (stat < 158)  return( 9);
  1501.     else if (stat < 168)  return(10);
  1502.     else if (stat < 178)  return(11);
  1503.     else if (stat < 188)  return(12);
  1504.     else if (stat < 198)  return(13);
  1505.     else if (stat < 218)  return(14);
  1506.     else if (stat < 228)  return(15);
  1507.     else                  return(17);
  1508. }
  1509.  
  1510.  
  1511. /* Returns a character's adjustment to disarm         -RAK-     */
  1512. int 
  1513. todis_adj()
  1514. {
  1515.     register int stat;
  1516.  
  1517.     stat = py.stats.use_stat[A_DEX];
  1518.     if      (stat <=  3)  return(-8);
  1519.     else if (stat ==  4)  return(-6);
  1520.     else if (stat ==  5)  return(-4);
  1521.     else if (stat ==  6)  return(-2);
  1522.     else if (stat ==  7)  return(-1);
  1523.     else if (stat <  13)  return( 0);
  1524.     else if (stat <  16)  return( 1);
  1525.     else if (stat <  18)  return( 2);
  1526.     else if (stat <  58)  return( 4); /* 18 to 18/49 -CFT */
  1527.     else if (stat <  88)  return( 5); /* 18/50 to 18/69 -CFT */
  1528.     else if (stat < 108)  return( 6); /* 18/70 to 18/89 -CFT */
  1529.     else if (stat < 118)  return( 7); /* 18/90 to 18/99 -CFT */
  1530.     else                  return( 8); /* 18/100 and over -CFT */
  1531. }
  1532.  
  1533.  
  1534. /* Returns a character's adjustment to damage         -JWT-     */
  1535. int 
  1536. todam_adj()
  1537. {
  1538.     register int stat;
  1539.  
  1540.     stat = py.stats.use_stat[A_STR];
  1541.     if      (stat <   4)  return(-2);
  1542.     else if (stat <   5)  return(-1);
  1543.     else if (stat <  16)  return( 0);
  1544.     else if (stat <  17)  return( 1);
  1545.     else if (stat <  18)  return( 2);
  1546.     else if (stat <  88)  return( 3); /* 18 to 18/69 -CFT */
  1547.     else if (stat <  98)  return( 4); /* 18/70 to 18/79 -CFT */
  1548.     else if (stat < 108)  return( 5); /* 18/80 to 18/89 -CFT */
  1549.     else if (stat < 118)  return( 5); /* 18/90 to 18/99 -CFT */
  1550.     else if (stat < 128)  return( 6); /* 18/100 to /109 -CFT */
  1551.     else if (stat < 138)  return( 7);
  1552.     else if (stat < 148)  return( 8);
  1553.     else if (stat < 158)  return( 9);
  1554.     else if (stat < 168)  return(10);
  1555.     else if (stat < 178)  return(11);
  1556.     else if (stat < 188)  return(12);
  1557.     else if (stat < 198)  return(13);
  1558.     else if (stat < 218)  return(14);
  1559.     else if (stat < 228)  return(16);
  1560.     else                  return(20);
  1561. }
  1562.  
  1563.  
  1564. /* Prints character-screen info                -RAK-     */
  1565. void 
  1566. prt_stat_block()
  1567. {
  1568.     register int32u       status;
  1569.     register struct misc *m_ptr;
  1570.     register int          i;
  1571.  
  1572.     m_ptr = &py.misc;
  1573.     prt_field(race[py.misc.prace].trace, 1, STAT_COLUMN);
  1574.     prt_field(class[py.misc.pclass].title, 2, STAT_COLUMN);
  1575.     prt_field(title_string(), 3, STAT_COLUMN);
  1576.     for (i = 0; i < 6; i++)
  1577.     prt_stat(i);
  1578.     prt_num("LEV", (int)m_ptr->lev, 12, STAT_COLUMN);
  1579.     prt_lnum("EXP", m_ptr->exp, 13, STAT_COLUMN);
  1580.     prt_num("MNA", m_ptr->cmana, 14, STAT_COLUMN);
  1581.     prt_num("MHP", m_ptr->mhp, 15, STAT_COLUMN);
  1582.     prt_num("CHP", m_ptr->chp, 16, STAT_COLUMN);
  1583.     prt_chp();               /* this will overwrite hp, in color, if
  1584.                     * needed. -CFT */
  1585.     prt_num("AC ", m_ptr->dis_ac, 18, STAT_COLUMN);
  1586.     prt_lnum("AU ", m_ptr->au, 19, STAT_COLUMN);
  1587.     prt_winner();
  1588.     prt_cut();
  1589.     prt_stun();
  1590.     prt_study();
  1591.     status = py.flags.status;
  1592.     if ((PY_HUNGRY | PY_WEAK) & status)
  1593.     prt_hunger();
  1594.     if (PY_BLIND & status)
  1595.     prt_blind();
  1596.     if (PY_CONFUSED & status)
  1597.     prt_confused();
  1598.     if (PY_FEAR & status)
  1599.     prt_afraid();
  1600.     if (PY_POISONED & status)
  1601.     prt_poisoned();
  1602.     if ((PY_SEARCH | PY_REST) & status)
  1603.     prt_state();
  1604. /* if speed non zero, print it, modify speed if Searching */
  1605.     if (py.flags.speed - ((PY_SEARCH & status) >> 8) != 0)
  1606.     prt_speed();
  1607.  
  1608.     prt_equippy_chars();
  1609. }
  1610.  
  1611. /* EQUIPMENT CHARACTER HANDLER  - DGK */
  1612. void
  1613. #ifdef __STDC__
  1614. prt_equippy_chars(void)
  1615. #else
  1616. prt_equippy_chars()
  1617. #endif                                    
  1618. {                                        
  1619.     int i, j;                              
  1620.     inven_type *i_ptr;                     
  1621.     vtype out_val;                           
  1622.                                           
  1623.     out_val[1]='\0';                       
  1624.     for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) {
  1625.     i_ptr = &inventory[i];                           
  1626.     j = i - INVEN_WIELD;                             
  1627.     
  1628.     if (!equippy_chars || (i_ptr->tval == TV_NOTHING))
  1629.         out_val[0] = ' ';                                
  1630.     else                                             
  1631.         out_val[0] = (int)(i_ptr->tchar);                
  1632.     
  1633.     put_buffer(out_val, 4, j);
  1634.     }
  1635. }
  1636.  
  1637.  
  1638. /* Draws entire screen                    -RAK-     */
  1639. void 
  1640. draw_cave()
  1641. {
  1642.     clear_screen();
  1643.     prt_stat_block();
  1644.     prt_map();
  1645.     prt_depth();
  1646. }
  1647.  
  1648.  
  1649. /* Prints the following information on the screen.    -JWT-     */
  1650. void 
  1651. put_character()
  1652. {
  1653.     register struct misc *m_ptr;
  1654.  
  1655.     m_ptr = &py.misc;
  1656.     clear_screen();
  1657.     put_buffer("Name        :", 2, 1);
  1658.     put_buffer("Race        :", 3, 1);
  1659.     put_buffer("Sex         :", 4, 1);
  1660.     put_buffer("Class       :", 5, 1);
  1661.     if (character_generated) {
  1662.     put_buffer(m_ptr->name, 2, 15);
  1663.     put_buffer(race[m_ptr->prace].trace, 3, 15);
  1664.     put_buffer((m_ptr->male ? "Male" : "Female"), 4, 15);
  1665.     put_buffer(class[m_ptr->pclass].title, 5, 15);
  1666.     }
  1667. }
  1668.  
  1669.  
  1670. /* Prints the following information on the screen.    -JWT-     */
  1671. void 
  1672. put_stats()
  1673. {
  1674.     register struct misc *m_ptr;
  1675.     register int          i, temp;
  1676.     vtype                 buf;
  1677.  
  1678.     m_ptr = &py.misc;
  1679.     for (i = 0; i < 6; i++) {
  1680.     cnv_stat(py.stats.use_stat[i], buf);
  1681.     put_buffer(stat_names[i], 2 + i, 61);
  1682.     put_buffer(buf, 2 + i, 66);
  1683.     if (py.stats.max_stat[i] > py.stats.cur_stat[i]) {
  1684.         /* this looks silly, but it happens because modify_stat() only
  1685.          * looks at cur_stat -CFT */
  1686.         temp = py.stats.cur_stat[i];
  1687.         py.stats.cur_stat[i] = py.stats.max_stat[i];
  1688.         cnv_stat (modify_stat(i,py.stats.mod_stat[i]), buf);
  1689.         py.stats.cur_stat[i] = temp; /* DON'T FORGET! -CFT */
  1690.         put_buffer(buf, 2 + i, 73);
  1691.     }
  1692.     }
  1693.     prt_num("+ To Hit    ", m_ptr->dis_th, 9, 1);
  1694.     prt_num("+ To Damage ", m_ptr->dis_td, 10, 1);
  1695.     prt_num("+ To AC     ", m_ptr->dis_tac, 11, 1);
  1696.     prt_num("  Total AC  ", m_ptr->dis_ac, 12, 1);
  1697. }
  1698.  
  1699.  
  1700. /* Returns a rating of x depending on y            -JWT-     */
  1701. const char *
  1702. likert(x, y)
  1703. int x, y;
  1704. {
  1705.     if ((x/y) < 0)
  1706.     return ("Very Bad");
  1707.  
  1708.     switch ((x / y)) {
  1709.       case 0:
  1710.       case 1:
  1711.     return ("Bad");
  1712.       case 2:
  1713.     return ("Poor");
  1714.       case 3:
  1715.       case 4:
  1716.     return ("Fair");
  1717.       case 5:
  1718.     return ("Good");
  1719.       case 6:
  1720.     return ("Very Good");
  1721.       case 7:
  1722.       case 8:
  1723.     return ("Excellent");
  1724.       case 9:
  1725.       case 10:
  1726.       case 11:
  1727.       case 12:
  1728.       case 13:
  1729.     return ("Superb");
  1730.       case 14:
  1731.       case 15:
  1732.       case 16:
  1733.       case 17:
  1734.     return ("Heroic");
  1735.       default:
  1736.     return ("Legendary");
  1737.     }
  1738. }
  1739.  
  1740.  
  1741. /* Prints age, height, weight, and SC            -JWT-     */
  1742. void 
  1743. put_misc1()
  1744. {
  1745.     register struct misc *m_ptr;
  1746.  
  1747.     m_ptr = &py.misc;
  1748.     prt_num("Age          ", (int)m_ptr->age, 2, 32);
  1749.     prt_num("Height       ", (int)m_ptr->ht, 3, 32);
  1750.     prt_num("Weight       ", (int)m_ptr->wt, 4, 32);
  1751.     prt_num("Social Class ", (int)m_ptr->sc, 5, 32);
  1752. }
  1753.  
  1754.  
  1755. /* Prints the following information on the screen.    -JWT-     */
  1756. void 
  1757. put_misc2()
  1758. {
  1759.     register struct misc *m_ptr;
  1760.  
  1761.     m_ptr = &py.misc;
  1762.     prt_num("Level      ", (int)m_ptr->lev, 9, 28);
  1763.     prt_lnum("Experience ", m_ptr->exp, 10, 28);
  1764.     prt_lnum("Max Exp    ", m_ptr->max_exp, 11, 28);
  1765.     if (m_ptr->lev >= MAX_PLAYER_LEVEL) {
  1766.     char                buf[40];    /* for this to look right, the
  1767.                      * following should be spaced the
  1768.                      * same as in the prt_lnum code...
  1769.                      * -CFT */
  1770.  
  1771.     sprintf(buf, "%s%9s", "Exp to Adv.", "****");
  1772.     put_buffer(buf, 12, 28);
  1773.     } else
  1774.     prt_lnum("Exp to Adv.", (int32) (player_exp[m_ptr->lev - 1] *
  1775.                      m_ptr->expfact / 100), 12, 28);
  1776.     prt_lnum("Gold       ", m_ptr->au, 13, 28);
  1777.     prt_num("Max Hit Points ", m_ptr->mhp, 9, 52);
  1778.     prt_num("Cur Hit Points ", m_ptr->chp, 10, 52);
  1779.     prt_num("Max Mana       ", m_ptr->mana, 11, 52);
  1780.     prt_num("Cur Mana       ", m_ptr->cmana, 12, 52);
  1781. }
  1782.  
  1783.  
  1784. /* Prints ratings on certain abilities            -RAK-     */
  1785. void 
  1786. put_misc3()
  1787. {
  1788.     int                   xbth, xbthb, xfos, xsrh, xstl, xdis, xsave, xdev;
  1789.     vtype                 xinfra;
  1790.     register struct misc *p_ptr;
  1791.  
  1792.     clear_from(14);
  1793.     p_ptr = &py.misc;
  1794.     xbth = p_ptr->bth + p_ptr->ptohit * BTH_PLUS_ADJ
  1795.     + (class_level_adj[p_ptr->pclass][CLA_BTH] * p_ptr->lev);
  1796.     xbthb = p_ptr->bthb + p_ptr->ptohit * BTH_PLUS_ADJ
  1797.     + (class_level_adj[p_ptr->pclass][CLA_BTHB] * p_ptr->lev);
  1798. /* this results in a range from 0 to 29 */
  1799.     xfos = 40 - p_ptr->fos;
  1800.     if (xfos < 0)
  1801.     xfos = 0;
  1802.     xsrh = p_ptr->srh;
  1803. /* this results in a range from 0 to 9 */
  1804.     xstl = p_ptr->stl + 1;
  1805.     xdis = p_ptr->disarm + 2 * todis_adj() + stat_adj(A_INT)
  1806.     + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
  1807.     xsave = p_ptr->save + stat_adj(A_WIS)
  1808.     + (class_level_adj[p_ptr->pclass][CLA_SAVE] * p_ptr->lev / 3);
  1809.     xdev = p_ptr->save + stat_adj(A_INT)
  1810.     + (class_level_adj[p_ptr->pclass][CLA_DEVICE] * p_ptr->lev / 3);
  1811.  
  1812.     (void)sprintf(xinfra, "%d feet", py.flags.see_infra * 10);
  1813.  
  1814.     put_buffer("(Miscellaneous Abilities)", 15, 25);
  1815.     put_buffer("Fighting    :", 16, 1);
  1816.     put_buffer(likert(xbth, 12), 16, 15);
  1817.     put_buffer("Bows/Throw  :", 17, 1);
  1818.     put_buffer(likert(xbthb, 12), 17, 15);
  1819.     put_buffer("Saving Throw:", 18, 1);
  1820.     put_buffer(likert(xsave, 6), 18, 15);
  1821.  
  1822.     put_buffer("Stealth     :", 16, 28);
  1823.     put_buffer(likert(xstl, 1), 16, 42);
  1824.     put_buffer("Disarming   :", 17, 28);
  1825.     put_buffer(likert(xdis, 8), 17, 42);
  1826.     put_buffer("Magic Device:", 18, 28);
  1827.     put_buffer(likert(xdev, 6), 18, 42);
  1828.  
  1829.     put_buffer("Perception  :", 16, 55);
  1830.     put_buffer(likert(xfos, 3), 16, 69);
  1831.     put_buffer("Searching   :", 17, 55);
  1832.     put_buffer(likert(xsrh, 6), 17, 69);
  1833.     put_buffer("Infra-Vision:", 18, 55);
  1834.     put_buffer(xinfra, 18, 69);
  1835. }
  1836.  
  1837.  
  1838. /* Used to display the character on the screen.        -RAK-     */
  1839. void 
  1840. display_char()
  1841. {
  1842.     put_character();
  1843.     put_misc1();
  1844.     put_stats();
  1845.     put_misc2();
  1846.     put_misc3();
  1847. }
  1848.  
  1849.  
  1850. /* Gets a name for the character            -JWT-     */
  1851. void 
  1852. get_name()
  1853. {
  1854.     char tmp[100];
  1855.  
  1856.     strcpy(tmp, py.misc.name);
  1857.     prt("Enter your player's name  [press <RETURN> when finished]", 21, 2);
  1858.     put_buffer(&blank_string[BLANK_LENGTH - 15], 2, 15);
  1859. #ifdef MAC
  1860. /*
  1861.  * Force player to give a name, would be nice to get name from chooser (STR
  1862.  * -16096), but that name might be too long 
  1863.  */
  1864.     while (!get_string(py.misc.name, 2, 15, 15) || py.misc.name[0] == 0);
  1865. #else
  1866.     if (!get_string(py.misc.name, 2, 15, 15) || py.misc.name[0] == 0) {
  1867.     strcpy(py.misc.name, tmp);
  1868.     put_buffer(tmp, 2, 15);
  1869.     }
  1870. #endif
  1871.     clear_from(20);
  1872. #ifdef MAC
  1873. /* Use the new name to set save file default name. */
  1874.     initsavedefaults();
  1875. #endif
  1876. }
  1877.  
  1878.  
  1879. /* Changes the name of the character            -JWT-     */
  1880. void 
  1881. change_name()
  1882. {
  1883.     register char c;
  1884.     register int  flag;
  1885.  
  1886. #ifndef MAC
  1887.     vtype         temp;
  1888.  
  1889. #endif
  1890.  
  1891.     flag = FALSE;
  1892.     display_char();
  1893.     do {
  1894.     prt("<f>ile character description. <c>hange character name.", 21, 2);
  1895.     c = inkey();
  1896.     switch (c) {
  1897.       case 'c':
  1898.         get_name();
  1899.         flag = TRUE;
  1900.         break;
  1901.       case 'f':
  1902. #ifdef MAC
  1903.     /* On mac, file_character() gets filename with std file dialog. */
  1904.         if (file_character())
  1905.         flag = TRUE;
  1906. #else
  1907.         prt("File name:", 0, 0);
  1908.         if (get_string(temp, 0, 10, 60) && temp[0])
  1909.         if (file_character(temp))
  1910.             flag = TRUE;
  1911. #endif
  1912.         break;
  1913.       case ESCAPE:
  1914.       case ' ':
  1915.       case '\n':
  1916.       case '\r':
  1917.         flag = TRUE;
  1918.         break;
  1919.       default:
  1920.         bell();
  1921.         break;
  1922.     }
  1923.     }
  1924.     while (!flag);
  1925. }
  1926.  
  1927.  
  1928. /* Destroy an item in the inventory            -RAK-     */
  1929. void 
  1930. inven_destroy(item_val)
  1931. int item_val;
  1932. {
  1933.     register int         j;
  1934.     register inven_type *i_ptr;
  1935.  
  1936.     i_ptr = &inventory[item_val];
  1937.     if ((i_ptr->number > 1) && (i_ptr->subval <= ITEM_SINGLE_STACK_MAX)) {
  1938.     i_ptr->number--;
  1939.     inven_weight -= i_ptr->weight;
  1940.     } else {
  1941.     inven_weight -= i_ptr->weight * i_ptr->number;
  1942.     for (j = item_val; j < inven_ctr - 1; j++)
  1943.         inventory[j] = inventory[j + 1];
  1944.     invcopy(&inventory[inven_ctr - 1], OBJ_NOTHING);
  1945.     inven_ctr--;
  1946.     }
  1947.     py.flags.status |= PY_STR_WGT;
  1948. }
  1949.  
  1950.  
  1951. /*
  1952.  * Copies the object in the second argument over the first argument. However,
  1953.  * the second always gets a number of one except for ammo etc. 
  1954.  */
  1955. void 
  1956. take_one_item(s_ptr, i_ptr)
  1957. register inven_type *s_ptr, *i_ptr;
  1958. {
  1959.     *s_ptr = *i_ptr;
  1960.     if ((s_ptr->number > 1) && (s_ptr->subval >= ITEM_SINGLE_STACK_MIN)
  1961.     && (s_ptr->subval <= ITEM_SINGLE_STACK_MAX))
  1962.     s_ptr->number = 1;
  1963. }
  1964.  
  1965.  
  1966. /* Drops an item from inventory to given location    -RAK-     */
  1967. void 
  1968. inven_drop(item_val, drop_all)
  1969. register int item_val, drop_all;
  1970. {
  1971.     int                  i;
  1972.     register inven_type *i_ptr;
  1973.     vtype                prt2;
  1974.     bigvtype             prt1;
  1975.  
  1976.     i_ptr = &inventory[item_val];
  1977.     if (cave[char_row][char_col].tptr != 0)
  1978.     (void)delete_object(char_row, char_col);
  1979.     i = popt();
  1980.     t_list[i] = *i_ptr;
  1981.     cave[char_row][char_col].tptr = i;
  1982.  
  1983.     if (item_val >= INVEN_WIELD)
  1984.     takeoff(item_val, -1);
  1985.     else {
  1986.     if (drop_all || i_ptr->number == 1) {
  1987.         inven_weight -= i_ptr->weight * i_ptr->number;
  1988.         inven_ctr--;
  1989.         while (item_val < inven_ctr) {
  1990.         inventory[item_val] = inventory[item_val + 1];
  1991.         item_val++;
  1992.         }
  1993.         invcopy(&inventory[inven_ctr], OBJ_NOTHING);
  1994.     } else {
  1995.         t_list[i].number = 1;
  1996.         inven_weight -= i_ptr->weight;
  1997.         i_ptr->number--;
  1998.     }
  1999.     objdes(prt1, &t_list[i], TRUE);
  2000.     (void)sprintf(prt2, "Dropped %s.", prt1);
  2001.     msg_print(prt2);
  2002.     }
  2003.     py.flags.status |= PY_STR_WGT;
  2004. }
  2005.  
  2006.  
  2007. /* Destroys a type of item on a given percent chance    -RAK-     */
  2008. int 
  2009. inven_damage(typ, perc)
  2010. #ifdef MSDOS
  2011. int (*typ) (inven_type *);
  2012.  
  2013. #else
  2014. int (*typ) ();
  2015.  
  2016. #endif
  2017. register int perc;
  2018.  
  2019. {
  2020.     register int index, i, j, offset;
  2021.     vtype        tmp_str, out_val;
  2022.  
  2023.     j = 0;
  2024.     offset = randint(inven_ctr);
  2025.     for (index = 0; index < inven_ctr; index++) {
  2026.     i = (index + offset) % inven_ctr; /* be clever and not destroy the first item */
  2027.     if ((*typ) (&inventory[i]) && (randint(100) < perc)) {
  2028.         objdes(tmp_str, &inventory[i], FALSE);
  2029.         sprintf(out_val, "%sour %s (%c) %s destroyed!",
  2030.             ((inventory[i].subval <= ITEM_SINGLE_STACK_MAX) &&
  2031.              (inventory[i].number > 1))    /* stacked single items */
  2032.             ? "One of y" : "Y",
  2033.             tmp_str, i + 'a',
  2034.             ((inventory[i].subval > ITEM_SINGLE_STACK_MAX) &&
  2035.              (inventory[i].number > 1))    /* stacked group items */
  2036.             ? "were" : "was");
  2037.         msg_print(out_val);
  2038.         inven_destroy(i);
  2039.         j++;
  2040.     }
  2041.     }
  2042.     return (j);
  2043. }
  2044.  
  2045.  
  2046. /* Computes current weight limit            -RAK-     */
  2047. int 
  2048. weight_limit()
  2049. {
  2050.     register int32 weight_cap;
  2051.  
  2052.     weight_cap = (long)py.stats.use_stat[A_STR] * (long)PLAYER_WEIGHT_CAP
  2053.     + (long)py.misc.wt;
  2054.     if (weight_cap > 3000L)
  2055.     weight_cap = 3000L;
  2056.     return ((int)weight_cap);
  2057. }
  2058.  
  2059.  
  2060. /* this code must be identical to the inven_carry() code below */
  2061. int 
  2062. inven_check_num(t_ptr)
  2063. register inven_type *t_ptr;
  2064. {
  2065.     register int i;
  2066.  
  2067.     if (inven_ctr < INVEN_WIELD)
  2068.     return TRUE;
  2069.     else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
  2070.     for (i = 0; i < inven_ctr; i++)
  2071.         if (inventory[i].tval == t_ptr->tval &&
  2072.         inventory[i].subval == t_ptr->subval &&
  2073.     /* make sure the number field doesn't overflow */
  2074.         ((int)inventory[i].number + (int)t_ptr->number < 256) &&
  2075.     /* they always stack (subval < 192), or else they have same p1 */
  2076.         ((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1))
  2077.     /* only stack if both or neither are identified */
  2078.         && (known1_p(&inventory[i]) == known1_p(t_ptr)))
  2079.         return TRUE;
  2080.     return FALSE;
  2081. }
  2082.  
  2083. /* return FALSE if picking up an object would change the players speed */
  2084. int 
  2085. inven_check_weight(i_ptr)
  2086. register inven_type *i_ptr;
  2087. {
  2088.     register int i, new_inven_weight;
  2089.  
  2090.     i = weight_limit();
  2091.     new_inven_weight = i_ptr->number * i_ptr->weight + inven_weight;
  2092.     if (i < new_inven_weight)
  2093.     i = new_inven_weight / (i + 1);
  2094.     else
  2095.     i = 0;
  2096.  
  2097.     if (pack_heavy != i)
  2098.     return FALSE;
  2099.     else
  2100.     return TRUE;
  2101. }
  2102.  
  2103.  
  2104. /* Are we strong enough for the current pack and weapon?  -CJS-     */
  2105. void 
  2106. check_strength()
  2107. {
  2108.     register int         i;
  2109.     register inven_type *i_ptr;
  2110.     static int           notlike = FALSE;
  2111.  
  2112.     i_ptr = &inventory[INVEN_WIELD];
  2113.     if (i_ptr->tval != TV_NOTHING
  2114.     && (py.stats.use_stat[A_STR] * 15 < i_ptr->weight)) {
  2115.     if (weapon_heavy == FALSE) {
  2116.         msg_print("You have trouble wielding such a heavy weapon.");
  2117.         weapon_heavy = TRUE;
  2118.         calc_bonuses();
  2119.     }
  2120.     } else if (weapon_heavy == TRUE) {
  2121.     weapon_heavy = FALSE;
  2122.     if (i_ptr->tval != TV_NOTHING)
  2123.         msg_print("You are strong enough to wield your weapon.");
  2124.     else
  2125.         msg_print("You feel relieved to put down your heavy weapon.");
  2126.     calc_bonuses();
  2127.     }
  2128.     i = weight_limit();
  2129.     if (i < inven_weight)
  2130.     i = inven_weight / (i + 1);
  2131.     else
  2132.     i = 0;
  2133.     if (pack_heavy != i) {
  2134.     if (pack_heavy < i)
  2135.         msg_print("Your pack is so heavy that it slows you down.");
  2136.     else
  2137.         msg_print("You move more easily under the weight of your pack.");
  2138.     change_speed(i - pack_heavy);
  2139.     pack_heavy = i;
  2140.     }
  2141.     py.flags.status &= ~PY_STR_WGT;
  2142.  
  2143.     if (py.misc.pclass == 2 && !notlike) {
  2144.         if ((i_ptr->tval == TV_SWORD || i_ptr->tval == TV_POLEARM)
  2145.             && ((i_ptr->flags2 & TR_BLESS_BLADE) == 0)) {
  2146.             notlike = TRUE;
  2147.             msg_print("You do not feel comfortable with your weapon.");
  2148.         }
  2149.     } else if (py.misc.pclass == 2 && notlike) {
  2150.         if (i_ptr->tval == TV_NOTHING) {
  2151.             notlike = FALSE;
  2152.             msg_print("You feel comfortable again after removing that weapon.");
  2153.         } else if (!(i_ptr->tval == TV_SWORD || i_ptr->tval == TV_POLEARM)
  2154.            || !((i_ptr->flags2 & TR_BLESS_BLADE) == 0)) {
  2155.             notlike = FALSE;
  2156.             msg_print("You feel comfortable with your weapon once more.");
  2157.         }
  2158.     }
  2159. }
  2160.  
  2161.  
  2162. /*
  2163.  * Add an item to players inventory.  Return the item position for a
  2164.  * description if needed.           -RAK- this code must be identical to
  2165.  * the inven_check_num() code above 
  2166.  */
  2167.  
  2168. /*
  2169.  * Okay, here's my inven_carry() function (from misc2.c, I think).  Just
  2170.  * replace the existing inven_carry() with this one, and items will sort into
  2171.  * place, with mage spellbooks coming first for mages, rangers, and rogues.
  2172.  * Also, this will make Tenser's book sort after all the mage books except
  2173.  * Raals, instead of in the middle of them (which always seemed strange to
  2174.  * me). -CFT 
  2175.  */
  2176.  
  2177. int 
  2178. inven_carry(i_ptr)
  2179. register inven_type *i_ptr;
  2180. {
  2181.     register int         locn = 0, i;
  2182.     register int         typ, subt;
  2183.     register inven_type *t_ptr;
  2184.     int                  known1p, always_known1p;
  2185.     int                  tval_tmp;  /* used to make magic books before pray
  2186.                     * books if magicuser */
  2187.     int                  stacked = FALSE;
  2188.  
  2189.     typ = i_ptr->tval;
  2190.     subt = i_ptr->subval;
  2191.     known1p = known1_p(i_ptr);
  2192.     always_known1p = (object_offset(i_ptr) == -1);
  2193.  
  2194.     if (inven_ctr >= INVEN_WIELD) /* sanity checking to prevent the inv from */
  2195.     inven_ctr = INVEN_WIELD;  /* running over the equipment list -CWS */
  2196.  
  2197. /*
  2198.  * to prevent nasty losses of objects, we first look through entire inven for
  2199.  * a place to stack, w/o assuming the inventory is sorted. -CFT 
  2200.  */
  2201.     if (subt >= ITEM_SINGLE_STACK_MIN) {
  2202.     for (locn = 0; locn < inven_ctr; locn++) {
  2203.         t_ptr = &inventory[locn];
  2204.         if (t_ptr->tval == typ &&
  2205.         t_ptr->subval == subt &&
  2206.     /* make sure the number field doesn't overflow */
  2207.         ((int)t_ptr->number + (int)i_ptr->number < 256) &&
  2208.     /* they always stack (subval < 192), or else they have same p1 */
  2209.         ((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1))
  2210.     /* only stack if both or neither are identified */
  2211.         && (known1_p(&inventory[locn]) == known1p)) {
  2212.         stacked = TRUE;       /* note that we did process the item -CFT */
  2213.         t_ptr->number += i_ptr->number;
  2214.  
  2215.     /* if player bought at bargin price, then make sure he can't sell back
  2216.      * for normal value.  This is unfair, since it robs the value from items,
  2217.      * but it does prevent the player from "milking" the stores for cash.
  2218.      */
  2219.         if (i_ptr->cost < t_ptr->cost)
  2220.             t_ptr->cost = i_ptr->cost;
  2221.         break;
  2222.         } /* if it stacks here */
  2223.     } /* for loop */
  2224.     } /* if it stacks, try to stack it... */
  2225.  
  2226.     if (!stacked) {
  2227.     /* either it doesn't stack anyway, or it didn't match anything in the inventory.
  2228.      * Now try to insert. -CFT */
  2229.  
  2230.     for (locn = 0;; locn++) {
  2231.         t_ptr = &inventory[locn];
  2232.  
  2233.     /* For items which are always known1p, i.e. never have a 'color',
  2234.      * insert them into the inventory in sorted order.  
  2235.      */
  2236.         if ((typ == TV_PRAYER_BOOK) && (class[py.misc.pclass].spell == MAGE))
  2237.         typ = TV_MAGIC_BOOK - 1;
  2238.     /* sort is in descending, so this will be immediately after magic books.
  2239.      * It helps that there is no tval that uses this. -CFT
  2240.      */
  2241.         tval_tmp = t_ptr->tval;
  2242.         if ((tval_tmp == TV_PRAYER_BOOK) &&
  2243.         (class[py.misc.pclass].spell == MAGE))
  2244.         tval_tmp = TV_MAGIC_BOOK - 1;
  2245.     /* sort is in descending, so this will be immediately after magic books.
  2246.      * It helps that there is no tval that uses this. -CFT
  2247.      */
  2248.         if ((typ > tval_tmp) ||     /* sort by desc tval */
  2249.         (always_known1p &&      /* if always known, then sort by inc level, */
  2250.          (typ == tval_tmp) &&    /* then by inc subval */
  2251.          ((i_ptr->level < t_ptr->level) ||
  2252.          ((i_ptr->level == t_ptr->level) && (subt < t_ptr->subval))))) {
  2253.         for (i = inven_ctr - 1; i >= locn; i--)
  2254.             inventory[i + 1] = inventory[i];
  2255.         inventory[locn] = *i_ptr;
  2256.         inven_ctr++;
  2257.         break;
  2258.         }
  2259.     }
  2260.     }
  2261.     inven_weight += i_ptr->number * i_ptr->weight;
  2262.     py.flags.status |= PY_STR_WGT;
  2263.     return locn;
  2264. }
  2265.  
  2266.  
  2267. /* Returns spell chance of failure for spell        -RAK-     */
  2268. int 
  2269. spell_chance(spell)
  2270. int spell;
  2271. {
  2272.     register spell_type *s_ptr;
  2273.     register int         chance;
  2274.     register int         stat;
  2275.     int                  minfail;
  2276.  
  2277.     s_ptr = &magic_spell[py.misc.pclass - 1][spell];
  2278.     chance = s_ptr->sfail - 3 * (py.misc.lev - s_ptr->slevel);
  2279.     if (class[py.misc.pclass].spell == MAGE)
  2280.     stat = A_INT;
  2281.     else
  2282.     stat = A_WIS;
  2283.     chance -= 3 * (stat_adj(stat) - 1);
  2284.     if (s_ptr->smana > py.misc.cmana)
  2285.     chance += 5 * (s_ptr->smana - py.misc.cmana);
  2286.     switch (stat_adj(stat)) {
  2287.       case 0:
  2288.     minfail = 50;
  2289.     break;               /* I doubt can cast spells with stat this
  2290.                     * low, anyways... */
  2291.       case 1:
  2292.     minfail = 12;
  2293.     break;               /* 8-14 stat */
  2294.       case 2:
  2295.     minfail = 8;
  2296.     break;               /* 15-17 stat */
  2297.       case 3:
  2298.     minfail = 5;
  2299.     break;               /* 18-18/49 stat */
  2300.       case 4:
  2301.     minfail = 4;
  2302.     break;               /* 18/50-18/69 */
  2303.       case 5:
  2304.     minfail = 4;
  2305.     break;               /* 18/70-18/89 */
  2306.       case 6:
  2307.     minfail = 3;
  2308.     break;               /* 18/90-18/99 */
  2309.       case 7:
  2310.     minfail = 3;
  2311.     break;               /* 18/100 */
  2312.       case 8:
  2313.       case 9:
  2314.       case 10:
  2315.     minfail = 2;
  2316.     break;               /* 18/101 - /130 */
  2317.       case 11:
  2318.       case 12:
  2319.     minfail = 2;
  2320.     break;               /* /131 - /150 */
  2321.       case 13:
  2322.       case 14:
  2323.     minfail = 1;
  2324.     break;               /* /151 - /170 */
  2325.       case 15:
  2326.       case 16:
  2327.     minfail = 1;
  2328.     break;               /* /171 - /200 */
  2329.       default:
  2330.     minfail = 0;
  2331.     break;               /* > 18/200 */
  2332.     }
  2333.     if ((minfail < 5) && (py.misc.pclass != 1) && (py.misc.pclass != 2))
  2334.     minfail = 5;           /* only mages/priests can get best
  2335.                     * chances... */
  2336.     if (py.misc.pclass == 2) {       /* Big prayer penalty for edged weapons
  2337.                     * -DGK */
  2338.     register inven_type *i_ptr = &inventory[INVEN_WIELD];
  2339.  
  2340.     if ((i_ptr->tval == TV_SWORD) || (i_ptr->tval == TV_POLEARM))
  2341.         if ((i_ptr->flags2 & TR_BLESS_BLADE) == 0)
  2342.         chance += 25;
  2343.     }
  2344.     if (chance > 95)
  2345.     chance = 95;
  2346.     else if (chance < minfail)
  2347.     chance = minfail;
  2348.     return chance;
  2349. }
  2350.  
  2351.  
  2352. /* Print list of spells                    -RAK-     */
  2353. /*
  2354.  * if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num >=0:
  2355.  * spells numbered by offset from nonconsec 
  2356.  */
  2357. void 
  2358. print_spells(spell, num, comment, nonconsec)
  2359. int         *spell;
  2360. register int num;
  2361. int          comment, nonconsec;
  2362. {
  2363.     register int         i, j;
  2364.     vtype                out_val;
  2365.     register spell_type *s_ptr;
  2366.     int                  col, offset;
  2367.     const char          *p;
  2368.     char                 spell_char;
  2369.  
  2370.     if (comment)
  2371.     col = 22;
  2372.     else
  2373.     col = 31;
  2374.     offset = (class[py.misc.pclass].spell == MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
  2375.     erase_line(1, col);
  2376.     put_buffer("Name", 1, col + 5);
  2377.     put_buffer("Lv Mana Fail", 1, col + 35);
  2378. /* only show the first 22 choices */
  2379.     if (num > 22)
  2380.     num = 22;
  2381.     for (i = 0; i < num; i++) {
  2382.     j = spell[i];
  2383.     s_ptr = &magic_spell[py.misc.pclass - 1][j];
  2384.     if (comment == FALSE)
  2385.         p = "";
  2386.     else if (j >= 32 ? ((spell_forgotten2 & (1L << (j - 32))) != 0)
  2387.          : ((spell_forgotten & (1L << j)) != 0))
  2388.         p = " forgotten";
  2389.     else if (j >= 32 ? ((spell_learned2 & (1L << (j - 32))) == 0)
  2390.          : ((spell_learned & (1L << j)) == 0))
  2391.         p = " unknown";
  2392.     else if (j >= 32 ? ((spell_worked2 & (1L << (j - 32))) == 0)
  2393.          : ((spell_worked & (1L << j)) == 0))
  2394.         p = " untried";
  2395.     else
  2396.         p = "";
  2397.     /* determine whether or not to leave holes in character choices,
  2398.      * nonconsec -1 when learning spells, consec offset>=0 when asking which
  2399.      * spell to cast 
  2400.      */
  2401.     if (nonconsec == -1)
  2402.         spell_char = 'a' + i;
  2403.     else
  2404.         spell_char = 'a' + j - nonconsec;
  2405.     (void)sprintf(out_val, "  %c) %-30s%2d %4d %3d%%%s", spell_char,
  2406.               spell_names[j + offset], s_ptr->slevel, s_ptr->smana,
  2407.               spell_chance(j), p);
  2408.     prt(out_val, 2 + i, col);
  2409.     }
  2410. }
  2411.  
  2412.  
  2413. /* Returns spell pointer                -RAK-     */
  2414. int 
  2415. get_spell(spell, num, sn, sc, prompt, first_spell)
  2416. int          *spell;
  2417. register int  num;
  2418. register int *sn, *sc;
  2419. const char   *prompt;
  2420. int           first_spell;
  2421. {
  2422.     register spell_type *s_ptr;
  2423.     int                  flag, redraw, offset, i;
  2424.     char                 choice;
  2425.     vtype                out_str, tmp_str;
  2426.  
  2427.     *sn = (-1);
  2428.     flag = FALSE;
  2429.     (void)sprintf(out_str, "(Spells %c-%c, *=List, <ESCAPE>=exit) %s",
  2430.        spell[0] + 'a' - first_spell, spell[num - 1] + 'a' - first_spell,
  2431.           prompt);
  2432.     redraw = FALSE;
  2433.     offset = (class[py.misc.pclass].spell == MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
  2434.     while (flag == FALSE && get_com(out_str, &choice)) {
  2435.     if (isupper((int)choice)) {
  2436.         *sn = choice - 'A' + first_spell;
  2437.     /* verify that this is in spell[], at most 22 entries in spell[] */
  2438.         for (i = 0; i < num; i++)
  2439.         if (*sn == spell[i])
  2440.             break;
  2441.         if (i == num)
  2442.         *sn = (-2);
  2443.         else {
  2444.         s_ptr = &magic_spell[py.misc.pclass - 1][*sn];
  2445.         (void)sprintf(tmp_str, "Cast %s (%d mana, %d%% fail)?",
  2446.                   spell_names[*sn + offset], s_ptr->smana,
  2447.                   spell_chance(*sn));
  2448.         if (get_check(tmp_str))
  2449.             flag = TRUE;
  2450.         else
  2451.             *sn = (-1);
  2452.         }
  2453.     } else if (islower((int)choice)) {
  2454.         *sn = choice - 'a' + first_spell;
  2455.     /* verify that this is in spell[], at most 22 entries in spell[] */
  2456.         for (i = 0; i < num; i++)
  2457.         if (*sn == spell[i])
  2458.             break;
  2459.         if (i == num)
  2460.         *sn = (-2);
  2461.         else
  2462.         flag = TRUE;
  2463.     } else if (choice == '*') {
  2464.     /* only do this drawing once */
  2465.         if (!redraw) {
  2466.         save_screen();
  2467.         redraw = TRUE;
  2468.         print_spells(spell, num, FALSE, first_spell);
  2469.         }
  2470.     } else if (isalpha((int)choice))
  2471.         *sn = (-2);
  2472.     else {
  2473.         *sn = (-1);
  2474.         bell();
  2475.     }
  2476.     if (*sn == -2) {
  2477.         sprintf(tmp_str, "You don't know that %s.",
  2478.         (class[py.misc.pclass].spell == MAGE) ? "spell" : "prayer");
  2479.         msg_print(tmp_str);
  2480.     }
  2481.     }
  2482.     if (redraw)
  2483.     restore_screen();
  2484.  
  2485.     erase_line(MSG_LINE, 0);
  2486.     if (flag)
  2487.     *sc = spell_chance(*sn);
  2488.  
  2489.     return (flag);
  2490. }
  2491.  
  2492.  
  2493. /* calculate number of spells player should have, and learn forget spells
  2494.  * until that number is met -JEW- 
  2495.  */
  2496. void 
  2497. calc_spells(stat)
  2498. int stat;
  2499. {
  2500.     register int    i;
  2501.     register int32u mask;
  2502.     int32u          spell_flag;
  2503.     int             j, offset;
  2504.     int             num_allowed, new_spells, num_known, levels;
  2505.     vtype           tmp_str;
  2506.     const char           *p;
  2507.     register struct misc *p_ptr;
  2508.     register spell_type  *msp_ptr;
  2509.  
  2510.     p_ptr = &py.misc;
  2511.     msp_ptr = &magic_spell[p_ptr->pclass - 1][0];
  2512.     if (stat == A_INT) {
  2513.     p = "spell";
  2514.     offset = SPELL_OFFSET;
  2515.     } else {
  2516.     p = "prayer";
  2517.     offset = PRAYER_OFFSET;
  2518.     }
  2519.  
  2520. /* check to see if know any spells greater than level, eliminate them */
  2521.     for (i = 31, mask = 0x80000000L; mask; mask >>= 1, i--) {
  2522.     if (mask & spell_learned) {
  2523.         if (msp_ptr[i].slevel > p_ptr->lev) {
  2524.         spell_learned &= ~mask;
  2525.         spell_forgotten |= mask;
  2526.         (void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  2527.                   spell_names[i + offset]);
  2528.         msg_print(tmp_str);
  2529.         }
  2530.     }
  2531.     if (mask & spell_learned2) {
  2532.         if (msp_ptr[i + 32].slevel > p_ptr->lev) {
  2533.         spell_learned2 &= ~mask;
  2534.         spell_forgotten2 |= mask;
  2535.         (void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  2536.                   spell_names[i + offset + 32]);
  2537.         msg_print(tmp_str);
  2538.         }
  2539.     }
  2540.     }
  2541.  
  2542. /* calc number of spells allowed */
  2543.     levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
  2544.     switch (stat_adj(stat)) {
  2545.       case 0:
  2546.     num_allowed = 0;
  2547.     break;
  2548.       case 1:
  2549.       case 2:
  2550.       case 3:
  2551.     num_allowed = 1 * levels;
  2552.     break;
  2553.       case 4:
  2554.       case 5:
  2555.     num_allowed = 3 * levels / 2;
  2556.     break;
  2557.       case 6:
  2558.     num_allowed = 2 * levels;
  2559.     break;
  2560.       default:
  2561.     num_allowed = 5 * levels / 2;
  2562.     break;
  2563.     }
  2564.  
  2565.     num_known = 0;
  2566.     for (mask = 0x1; mask; mask <<= 1) {
  2567.     if (mask & spell_learned)
  2568.         num_known++;
  2569.     if (mask & spell_learned2)
  2570.         num_known++;
  2571.     }
  2572.  
  2573.     new_spells = num_allowed - num_known;
  2574.  
  2575.     if (new_spells > 0) {
  2576.  
  2577.     /* remember forgotten spells while forgotten spells exist of new_spells
  2578.      * positive, remember the spells in the order that they were learned 
  2579.      */
  2580.     for (i = 0; ((spell_forgotten | spell_forgotten2) && new_spells
  2581.              && (i < num_allowed) && (i < 64)); i++) {
  2582.     /* j is (i+1)th spell learned */
  2583.         j = spell_order[i];
  2584.  
  2585.     /* shifting by amounts greater than number of bits in long gives an
  2586.      * undefined result, so don't shift for unknown spells 
  2587.      */
  2588.         if (j == 99)
  2589.         continue;       /* don't process unknown spells... -CFT */
  2590.  
  2591.         if (j < 32) {       /* use spell_learned, spell_forgotten...
  2592.                     * -CFT */
  2593.         mask = 1L << j;       /* bit in spell fields */
  2594.         if (mask & spell_forgotten) {
  2595.             if (msp_ptr[j].slevel <= p_ptr->lev) {
  2596.             spell_forgotten &= ~mask;
  2597.             spell_learned |= mask;
  2598.             new_spells--;
  2599.             (void)sprintf(tmp_str, "You have remembered the %s of %s.", p,
  2600.                       spell_names[j + offset]);
  2601.             msg_print(tmp_str);
  2602.             } else
  2603.             num_allowed++;    /* if was too high lv to remember */
  2604.         } /* if mask&spell_forgotten */
  2605.         }
  2606.          /* j < 32 */ 
  2607.         else {           /* j > 31, use spell_learned2,
  2608.                     * spell_forgotten2... -CFT */
  2609.         mask = 1L << (j - 32);    /* bit in spell fields */
  2610.         if (mask & spell_forgotten2) {
  2611.             if (msp_ptr[j].slevel <= p_ptr->lev) {
  2612.             spell_forgotten2 &= ~mask;
  2613.             spell_learned2 |= mask;
  2614.             new_spells--;
  2615.             (void)sprintf(tmp_str, "You have remembered the %s of %s.", p,
  2616.                       spell_names[j + offset]);
  2617.             msg_print(tmp_str);
  2618.             } else
  2619.             num_allowed++;    /* if was too high lv to remember */
  2620.         } /* if mask&spell_forgotten2 */
  2621.         } /* j > 31 */
  2622.     } /* for loop... */
  2623.  
  2624.     if (new_spells > 0) {
  2625.     /* determine which spells player can learn */
  2626.     /*
  2627.      * must check all spells here, in gain_spell() we actually check if
  2628.      * the books are present 
  2629.      */
  2630.     /* only bother with spells learnable by class -CFT */
  2631.         spell_flag = spellmasks[py.misc.pclass][0] & ~spell_learned;
  2632.         mask = 0x1;
  2633.         i = 0;
  2634.         for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
  2635.         if (spell_flag & mask) {
  2636.             spell_flag &= ~mask;
  2637.             if (msp_ptr[j].slevel <= p_ptr->lev)
  2638.             i++;
  2639.         }
  2640.     /* only bother with spells learnable by class -CFT */
  2641.         spell_flag = spellmasks[py.misc.pclass][1] & ~spell_learned2;
  2642.         mask = 0x1;
  2643.         for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
  2644.         if (spell_flag & mask) {
  2645.             spell_flag &= ~mask;
  2646.             if (msp_ptr[j + 32].slevel <= p_ptr->lev)
  2647.             i++;
  2648.         }
  2649.         if (new_spells > i)
  2650.         new_spells = i;
  2651.     }
  2652.     } else if (new_spells < 0) {
  2653.  
  2654.     /* forget spells until new_spells zero or no more spells know, spells are
  2655.      * forgotten in the opposite order that they were learned 
  2656.      */
  2657.     for (i = 63; new_spells && (spell_learned | spell_learned2); i--) {
  2658.     /* j is the (i+1)th spell learned */
  2659.         j = spell_order[i];
  2660.  
  2661.     /* shifting by amounts greater than number of bits in long gives an
  2662.      * undefined result, so don't shift for unknown spells 
  2663.      */
  2664.         if (j == 99)
  2665.         continue;       /* don't process unknown spells... -CFT */
  2666.  
  2667.         if (j < 32) {       /* use spell_learned, spell_forgotten...
  2668.                     * -CFT */
  2669.         mask = 1L << j;       /* bit in spell fields */
  2670.         if (mask & spell_learned) {
  2671.             spell_learned &= ~mask;
  2672.             spell_forgotten |= mask;
  2673.             new_spells++;
  2674.             (void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  2675.                   spell_names[j + offset]);
  2676.             msg_print(tmp_str);
  2677.         } /* if mask&spell_learned */
  2678.         }
  2679.          /* j < 32 */ 
  2680.         else {           /* j > 31, use spell_learned2,
  2681.                     * spell_forgotten2... -CFT */
  2682.         mask = 1L << (j - 32);    /* bit in spell fields */
  2683.         if (mask & spell_learned2) {
  2684.             spell_learned2 &= ~mask;
  2685.             spell_forgotten2 |= mask;
  2686.             new_spells++;
  2687.             (void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  2688.                   spell_names[j + offset]);
  2689.             msg_print(tmp_str);
  2690.         } /* if mask&spell_learned2 */
  2691.         } /* j > 31 */
  2692.     } /* for loop... */
  2693.     new_spells = 0;           /* we've forgotten, so we shouldn't be
  2694.                     * learning any... */
  2695.     }
  2696.     if (new_spells != py.flags.new_spells) {
  2697.     if (new_spells > 0 && py.flags.new_spells == 0) {
  2698.         (void)sprintf(tmp_str, "You can learn some new %ss now.", p);
  2699.         msg_print(tmp_str);
  2700.     }
  2701.     py.flags.new_spells = new_spells;
  2702.     py.flags.status |= PY_STUDY;
  2703.     }
  2704. }
  2705.  
  2706.  
  2707. /* gain spells when player wants to        - jw */
  2708. void 
  2709. gain_spells()
  2710. {
  2711.     char                query;
  2712.     int                 stat, diff_spells, new_spells;
  2713.     int                 spells[63], offset, last_known;
  2714.     register int        i, j;
  2715.     register int32u     spell_flag = 0, spell_flag2 = 0, mask;
  2716.     vtype               tmp_str;
  2717.     struct misc         *p_ptr;
  2718.     register spell_type *msp_ptr;
  2719.  
  2720.     if (!py.misc.pclass) {
  2721.     msg_print("A warrior learn magic???  HA!");
  2722.     return;
  2723.     }
  2724.     i = 0;
  2725.     if (py.flags.blind > 0)
  2726.     msg_print("You can't see to read your spell book!");
  2727.     else if (no_light())
  2728.     msg_print("You have no light to read by.");
  2729.     else if (py.flags.confused > 0)
  2730.     msg_print("You are too confused.");
  2731.     else
  2732.     i = 1;
  2733.     if (i == 0)
  2734.     return;
  2735.  
  2736.     new_spells = py.flags.new_spells;
  2737.     diff_spells = 0;
  2738.     p_ptr = &py.misc;
  2739.     msp_ptr = &magic_spell[p_ptr->pclass - 1][0];
  2740.     if (class[p_ptr->pclass].spell == MAGE) {
  2741.     stat = A_INT;
  2742.     offset = SPELL_OFFSET;
  2743.     } else {
  2744.     stat = A_WIS;
  2745.     offset = PRAYER_OFFSET;
  2746.     }
  2747.  
  2748.     for (last_known = 0; last_known < 64; last_known++)
  2749.     if (spell_order[last_known] == 99)
  2750.         break;
  2751.  
  2752.     if (!new_spells) {
  2753.     (void)sprintf(tmp_str, "You can't learn any new %ss!",
  2754.               (stat == A_INT ? "spell" : "prayer"));
  2755.     msg_print(tmp_str);
  2756.     free_turn_flag = TRUE;
  2757.     } else {
  2758.     /* determine which spells player can learn */
  2759.     /* mages need the book to learn a spell, priests do not need the book */
  2760.     spell_flag = 0;
  2761.     spell_flag2 = 0;
  2762.     for (i = 0; i < inven_ctr; i++)
  2763.         if (((stat == A_INT) && (inventory[i].tval == TV_MAGIC_BOOK))
  2764.         || ((stat == A_WIS) && (inventory[i].tval == TV_PRAYER_BOOK))) {
  2765.         spell_flag |= inventory[i].flags;
  2766.         spell_flag2 |= inventory[i].flags2;
  2767.         }
  2768.     }
  2769.  
  2770. /* clear bits for spells already learned */
  2771.     spell_flag &= ~spell_learned;
  2772.     spell_flag2 &= ~spell_learned2;
  2773.  
  2774.     mask = 0x1;
  2775.     i = 0;
  2776.     for (j = 0, mask = 0x1; (spell_flag | spell_flag2); mask <<= 1, j++) {
  2777.     if (spell_flag & mask) {
  2778.         spell_flag &= ~mask;
  2779.         if (msp_ptr[j].slevel <= p_ptr->lev) {
  2780.         spells[i] = j;
  2781.         i++;
  2782.         }
  2783.     }
  2784.     if (spell_flag2 & mask) {
  2785.         spell_flag2 &= ~mask;
  2786.         if (msp_ptr[j + 32].slevel <= p_ptr->lev) {
  2787.         spells[i] = j + 32;
  2788.         i++;
  2789.         }
  2790.     }
  2791.     }
  2792.  
  2793.     if (new_spells > i) {
  2794.     msg_print("You seem to be missing a book.");
  2795.     diff_spells = new_spells - i;
  2796.     new_spells = i;
  2797.     }
  2798.     if (new_spells == 0);
  2799.     else if (stat == A_INT) {
  2800.     /* get to choose which mage spells will be learned */
  2801.     save_screen();
  2802.     print_spells(spells, i, FALSE, -1);
  2803.     while (new_spells && get_com("Learn which spell?", &query)) {
  2804.         j = query - 'a';
  2805.  
  2806.     /* test j < 23 in case i is greater than 22, only 22 spells are
  2807.      * actually shown on the screen, so limit choice to those 
  2808.      */
  2809.         if (j >= 0 && j < i && j < 22) {
  2810.         new_spells--;
  2811.         if (spells[j] < 32)
  2812.             spell_learned |= 1L << spells[j];
  2813.         else
  2814.             spell_learned2 |= 1L << (spells[j] - 32);
  2815.         spell_order[last_known++] = spells[j];
  2816.         for (; j <= i - 1; j++)
  2817.             spells[j] = spells[j + 1];
  2818.         i--;
  2819.         erase_line(j + 1, 31);
  2820.         print_spells(spells, i, FALSE, -1);
  2821.         } else
  2822.         bell();
  2823.     }
  2824.     restore_screen();
  2825.     } else {
  2826.     /* pick a prayer at random */
  2827.     while (new_spells) {
  2828.         j = randint(i) - 1;
  2829.         if (spells[j] < 32)
  2830.         spell_learned |= 1L << spells[j];
  2831.         else
  2832.         spell_learned2 |= 1L << (spells[j] - 32);
  2833.         spell_order[last_known++] = spells[j];
  2834.         (void)sprintf(tmp_str,
  2835.               "You have learned the prayer of %s.",
  2836.               spell_names[spells[j] + offset]);
  2837.         msg_print(tmp_str);
  2838.         for (; j <= i - 1; j++)
  2839.         spells[j] = spells[j + 1];
  2840.         i--;
  2841.         new_spells--;
  2842.     }
  2843.     }
  2844.     py.flags.new_spells = new_spells + diff_spells;
  2845.     if (py.flags.new_spells == 0)
  2846.     py.flags.status |= PY_STUDY;
  2847. /* set the mana for first level characters when they learn first spell */
  2848.     if (py.misc.mana == 0)
  2849.     calc_mana(stat);
  2850. }
  2851.  
  2852.  
  2853.  
  2854. /* Gain some mana if you know at least one spell    -RAK-     */
  2855. void 
  2856. calc_mana(stat)
  2857. int stat;
  2858. {
  2859.     register int          new_mana, levels;
  2860.     register struct misc *p_ptr;
  2861.     register int32        value;
  2862.     register int          i;
  2863.     register inven_type  *i_ptr;
  2864.     int                   amrwgt, maxwgt;
  2865.  
  2866.     p_ptr = &py.misc;
  2867.     if (spell_learned != 0 || spell_learned2 != 0) {
  2868.     levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
  2869.     switch (stat_adj(stat)) {
  2870.       case 0:
  2871.         new_mana = 0;
  2872.         break;
  2873.       case 1:
  2874.       case 2:
  2875.         new_mana = 1 * levels;
  2876.         break;
  2877.       case 3:
  2878.         new_mana = 3 * levels / 2;
  2879.         break;
  2880.       case 4:
  2881.         new_mana = 2 * levels;
  2882.         break;
  2883.       case 5:
  2884.         new_mana = 5 * levels / 2;
  2885.         break;
  2886.       case 6:
  2887.         new_mana = 3 * levels;
  2888.         break;
  2889.       case 7:
  2890.         new_mana = 4 * levels;
  2891.         break;
  2892.       case 8:
  2893.         new_mana = 9 * levels / 2;
  2894.         break;
  2895.       case 9:
  2896.         new_mana = 5 * levels;
  2897.         break;
  2898.       case 10:
  2899.         new_mana = 11 * levels / 2;
  2900.         break;
  2901.       case 11:
  2902.         new_mana = 6 * levels;
  2903.         break;
  2904.       case 12:
  2905.         new_mana = 13 * levels / 2;
  2906.         break;
  2907.       case 13:
  2908.         new_mana = 7 * levels;
  2909.         break;
  2910.       case 14:
  2911.         new_mana = 15 * levels / 2;
  2912.         break;
  2913.       default:
  2914.         new_mana = 8 * levels;
  2915.         break;
  2916.     }
  2917.     /* increment mana by one, so that first level chars have 2 mana */
  2918.     if (new_mana > 0)
  2919.         new_mana++;
  2920.     if ((inventory[INVEN_HANDS].tval != TV_NOTHING) &&
  2921.         !((inventory[INVEN_HANDS].flags & TR_FREE_ACT) ||
  2922.           ((inventory[INVEN_HANDS].flags & TR_DEX) &&
  2923.            (inventory[INVEN_HANDS].p1 > 0)))
  2924. /* gauntlets of dex (or free action - DGK) can hardly interfere w/ spellcasting!
  2925.  * But cursed ones can! -CFT */
  2926.  
  2927.         &&(py.misc.pclass == 1 || py.misc.pclass == 3 || py.misc.pclass == 4)) {
  2928.         new_mana = (3 * new_mana) / 4;
  2929.     }
  2930.     /* Start of **NEW ENCUMBRANCE CALCULATION**    -DGK- */
  2931.     amrwgt = 0;
  2932.     for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) {
  2933.         i_ptr = &inventory[i];
  2934.         switch (i) {
  2935.           case INVEN_HEAD:
  2936.           case INVEN_BODY:
  2937.           case INVEN_ARM:
  2938.           case INVEN_HANDS:
  2939.           case INVEN_FEET:
  2940.           case INVEN_OUTER:
  2941.         amrwgt += i_ptr->weight;
  2942.         }
  2943.     }
  2944.     switch (py.misc.pclass) {
  2945.       case 1:
  2946.         maxwgt = 300;
  2947.         break;
  2948.       case 2:
  2949.         maxwgt = 350;
  2950.         break;
  2951.       case 3:
  2952.         maxwgt = 350;
  2953.         break;
  2954.       case 4:
  2955.         maxwgt = 400;
  2956.         break;
  2957.       case 5:
  2958.         maxwgt = 400;
  2959.         break;
  2960.       default:
  2961.         maxwgt = 0;
  2962.     }
  2963.     if (amrwgt > maxwgt)
  2964.         new_mana -= ((amrwgt - maxwgt) / 10);
  2965.     /* end of new mana calc */
  2966.  
  2967.     /* if low int/wis, gloves, and lots of heavy armor, new_mana could be
  2968.      * negative.  This would be very unlikely, except when int/wis was high
  2969.      * enough to compensate for armor, but was severly drained by an annoying
  2970.      * monster.  Since the following code blindly assumes that new_mana is >=
  2971.      * 0, we must do the work and return here. -CFT 
  2972.      */
  2973.     if (new_mana < 1) {
  2974.         p_ptr->cmana = p_ptr->cmana_frac = p_ptr->mana = 0;
  2975.         py.flags.status |= PY_MANA;
  2976.         return;           /* now return before we reach code that
  2977.                     * assumes new_mana is positive.... */
  2978.     }
  2979.     /* mana can be zero when creating character */
  2980.     if (p_ptr->mana != new_mana) {
  2981.         if (p_ptr->mana != 0) {
  2982.         /*
  2983.          * change current mana proportionately to change of max mana,
  2984.          * divide first to avoid overflow, little loss of accuracy 
  2985.          */
  2986.         value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac)
  2987.             / p_ptr->mana * new_mana;
  2988.         p_ptr->cmana = value >> 16;
  2989.         p_ptr->cmana_frac = value & 0xFFFF;
  2990.         } else {
  2991.         p_ptr->cmana = new_mana;
  2992.         p_ptr->cmana_frac = 0;
  2993.         }
  2994.         p_ptr->mana = new_mana;
  2995.     /* can't print mana here, may be in store or inventory mode */
  2996.         py.flags.status |= PY_MANA;
  2997.     }
  2998.     } else if (p_ptr->mana != 0) {
  2999.     p_ptr->mana = 0;
  3000.     p_ptr->cmana = 0;
  3001.     /* can't print mana here, may be in store or inventory mode */
  3002.     py.flags.status |= PY_MANA;
  3003.     }
  3004. }
  3005.  
  3006.  
  3007. /* Increases hit points and level            -RAK-     */
  3008. static void 
  3009. gain_level()
  3010. {
  3011.     vtype               out_val;
  3012.     register struct misc *p_ptr;
  3013.     register class_type *c_ptr;
  3014.  
  3015.     p_ptr = &py.misc;
  3016.     p_ptr->lev++;
  3017.     (void)sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev);
  3018.     msg_print(out_val);
  3019.     calc_hitpoints();
  3020.     prt_level();
  3021.     prt_title();
  3022.     c_ptr = &class[p_ptr->pclass];
  3023.     if (c_ptr->spell == MAGE) {
  3024.     calc_spells(A_INT);
  3025.     calc_mana(A_INT);
  3026.     } else if (c_ptr->spell == PRIEST) {
  3027.     calc_spells(A_WIS);
  3028.     calc_mana(A_WIS);
  3029.     }
  3030. }
  3031.  
  3032. /* Prints experience                    -RAK-     */
  3033. void 
  3034. prt_experience()
  3035. {
  3036.     register struct misc *p_ptr;
  3037.     char out_val[100];
  3038.     
  3039.     p_ptr = &py.misc;
  3040.     if (p_ptr->exp > MAX_EXP)
  3041.     p_ptr->exp = MAX_EXP;
  3042.     if (p_ptr->lev < MAX_PLAYER_LEVEL)
  3043.     {
  3044.     while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp
  3045.            && p_ptr->lev < MAX_PLAYER_LEVEL){
  3046.         gain_level();
  3047.         if (p_ptr->exp > p_ptr->max_exp) {
  3048.         /* level was actually gained, not restored:
  3049.          * this 300 is arbitrary, but it makes human ages work okay,
  3050.          * and I chose the other racial age adjs based on this as well -CFT
  3051.          */
  3052.         p_ptr->age += randint((int16u)class[p_ptr->pclass].age_adj *
  3053.                       (int16u)race[p_ptr->prace].m_age)/300;
  3054.         }
  3055.     }
  3056.     }
  3057.     if (p_ptr->exp > p_ptr->max_exp)
  3058.     p_ptr->max_exp = p_ptr->exp;
  3059.     (void) sprintf(out_val, "%8ld", (long)p_ptr->exp);
  3060.     put_buffer(out_val, 13, STAT_COLUMN+4);
  3061. }
  3062.  
  3063.  
  3064. /* Calculate the players hit points */
  3065. void 
  3066. calc_hitpoints()
  3067. {
  3068.     register int          hitpoints;
  3069.     register struct misc *p_ptr;
  3070.     register int32        value;
  3071.  
  3072.     p_ptr = &py.misc;
  3073.     hitpoints = player_hp[p_ptr->lev - 1] + (con_adj() * p_ptr->lev);
  3074. /* always give at least one point per level + 1 */
  3075.     if (hitpoints < (p_ptr->lev + 1))
  3076.     hitpoints = p_ptr->lev + 1;
  3077.  
  3078.     if (py.flags.status & PY_HERO)
  3079.     hitpoints += 10;
  3080.     if (py.flags.status & PY_SHERO)
  3081.     hitpoints += 30;
  3082.  
  3083. /* mhp can equal zero while character is being created */
  3084.     if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0)) {
  3085.     /* change current hit points proportionately to change of mhp, divide
  3086.      * first to avoid overflow, little loss of accuracy 
  3087.      */
  3088.     value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp
  3089.         * hitpoints;
  3090.     p_ptr->chp = value >> 16;
  3091.     p_ptr->chp_frac = value & 0xFFFF;
  3092.     p_ptr->mhp = hitpoints;
  3093.  
  3094.     /* can't print hit points here, may be in store or inventory mode */
  3095.     py.flags.status |= PY_HP;
  3096.     }
  3097. }
  3098.  
  3099.  
  3100. /* Inserts a string into a string                 */
  3101. void 
  3102. insert_str(object_str, mtc_str, insert)
  3103. char       *object_str;
  3104. const char *mtc_str, *insert;
  3105. {
  3106.     int            obj_len;
  3107.     char          *bound, *pc;
  3108.     register int   i, mtc_len;
  3109.     register char *temp_obj;
  3110.     const char    *temp_mtc;
  3111.     char           out_val[80];
  3112.  
  3113.     mtc_len = strlen(mtc_str);
  3114.     obj_len = strlen(object_str);
  3115.     bound = object_str + obj_len - mtc_len;
  3116.     for (pc = object_str; pc <= bound; pc++) {
  3117.     temp_obj = pc;
  3118.     temp_mtc = mtc_str;
  3119.     for (i = 0; i < mtc_len; i++)
  3120.         if (*temp_obj++ != *temp_mtc++)
  3121.         break;
  3122.     if (i == mtc_len)
  3123.         break;
  3124.     }
  3125.  
  3126.     if (pc <= bound) {
  3127.     (void)strncpy(out_val, object_str, (int)(pc - object_str));
  3128.     out_val[(int)(pc - object_str)] = '\0';
  3129.     if (insert)
  3130.         (void)strcat(out_val, insert);
  3131.     (void)strcat(out_val, (char *)(pc + mtc_len));
  3132.     (void)strcpy(object_str, out_val);
  3133.     }
  3134. }
  3135.  
  3136.  
  3137. void 
  3138. insert_lnum(object_str, mtc_str, number, show_sign)
  3139. char                *object_str;
  3140. register const char *mtc_str;
  3141. int32                number;
  3142. int                  show_sign;
  3143. {
  3144.     int            mlen;
  3145.     vtype          str1, str2;
  3146.     register char *string, *tmp_str;
  3147.     int            flag;
  3148.  
  3149.     flag = 1;
  3150.     mlen = strlen(mtc_str);
  3151.     tmp_str = object_str;
  3152.     do {
  3153.     string = (char *) index(tmp_str, mtc_str[0]);
  3154.     if (string == 0)
  3155.         flag = 0;
  3156.     else {
  3157.         flag = strncmp(string, mtc_str, mlen);
  3158.         if (flag)
  3159.         tmp_str = string + 1;
  3160.     }
  3161.     }
  3162.     while (flag);
  3163.     if (string) {
  3164.     (void)strncpy(str1, object_str, (int)(string - object_str));
  3165.     str1[(int)(string - object_str)] = '\0';
  3166.     (void)strcpy(str2, string + mlen);
  3167.     if ((number >= 0) && (show_sign))
  3168.         (void)sprintf(object_str, "%s+%ld%s", str1, (long)number, str2);
  3169.     else
  3170.         (void)sprintf(object_str, "%s%ld%s", str1, (long)number, str2);
  3171.     }
  3172. }
  3173.  
  3174.  
  3175. /* lets anyone enter wizard mode after a disclaimer...        - JEW - */
  3176. int 
  3177. enter_wiz_mode()
  3178. {
  3179.     register int answer;
  3180.  
  3181.     if (!is_wizard(player_uid))
  3182.     return FALSE;
  3183.     if (!noscore) {
  3184.     msg_print("Wizard mode is for debugging and experimenting.");
  3185.     answer = get_Yn(
  3186.             "The game will not be scored if you enter wizard mode. Are you sure?");
  3187.     }
  3188.     if (noscore || answer) {
  3189.     noscore |= 0x2;
  3190.     wizard = TRUE;
  3191.     return (TRUE);
  3192.     }
  3193.     return (FALSE);
  3194. }
  3195.  
  3196.  
  3197. /* Weapon weight VS strength and dexterity        -RAK-     */
  3198. int 
  3199. attack_blows(weight, wtohit)
  3200. int  weight;
  3201. int *wtohit;
  3202. {
  3203.     register int adj_weight;
  3204.     register int str_index, dex_index, s, d;
  3205.  
  3206.     s = py.stats.use_stat[A_STR];
  3207.     d = py.stats.use_stat[A_DEX];
  3208.     if (s * 15 < weight) {
  3209.     *wtohit = s * 15 - weight;
  3210.     return 1;
  3211.     } else {
  3212.     *wtohit = 0;
  3213.     if (d < 10)
  3214.         dex_index = 0;
  3215.     else if (d < 19)
  3216.         dex_index = 1;
  3217.     else if (d < 68)
  3218.         dex_index = 2;
  3219.     else if (d < 108)
  3220.         dex_index = 3;
  3221.     else if (d < 118)
  3222.         dex_index = 4;
  3223.     else if (d == 118)
  3224.         dex_index = 5;
  3225.     else if (d < 128)
  3226.         dex_index = 6;
  3227.     else if (d < 138)
  3228.         dex_index = 7;
  3229.     else if (d < 148)
  3230.         dex_index = 8;
  3231.     else if (d < 158)
  3232.         dex_index = 9;
  3233.     else if (d < 168)
  3234.         dex_index = 10;
  3235.     else
  3236.         dex_index = 11;
  3237.  
  3238.     switch (py.misc.pclass) { /* new class-based weight penalties -CWS */
  3239.     case 0:                /* Warriors */
  3240.         adj_weight = ((s * 10) / ((weight < 30) ? 30 : weight));
  3241.         break;
  3242.     case 1:                /* Mages */
  3243.         adj_weight = ((s * 4) / ((weight < 40) ? 40 : weight));
  3244.         break;
  3245.     case 2:                /* Priests */
  3246.         adj_weight = ((s * 7) / ((weight < 35) ? 35 : weight));
  3247.         break;
  3248.     case 3:                /* Rogues */
  3249.         adj_weight = ((s * 6) / ((weight < 30) ? 30 : weight));
  3250.         break;
  3251.     case 4:                /* Rangers */
  3252.         adj_weight = ((s * 8) / ((weight < 35) ? 35 : weight));
  3253.         break;
  3254.     default:            /* Paladins */
  3255.         adj_weight = ((s * 8) / ((weight < 30) ? 30 : weight));
  3256.         break;
  3257.     }
  3258.  
  3259.     if (adj_weight < 2)
  3260.         str_index = 0;
  3261.     else if (adj_weight < 3)
  3262.         str_index = 1;
  3263.     else if (adj_weight < 4)
  3264.         str_index = 2;
  3265.     else if (adj_weight < 6)
  3266.         str_index = 3;
  3267.     else if (adj_weight < 8)
  3268.         str_index = 4;
  3269.     else if (adj_weight < 10)
  3270.         str_index = 5;
  3271.     else if (adj_weight < 13)
  3272.         str_index = 6;
  3273.     else if (adj_weight < 15)
  3274.         str_index = 7;
  3275.     else if (adj_weight < 18)
  3276.         str_index = 8;
  3277.     else if (adj_weight < 20)
  3278.         str_index = 9;
  3279.     else
  3280.         str_index = 10;
  3281.  
  3282.     s = 0;                /* do Weapons of Speed */
  3283.     for (d = INVEN_WIELD; d < INVEN_AUX; d++)
  3284.         if (inventory[d].flags2 & TR_ATTACK_SPD)
  3285.         s += inventory[d].p1;
  3286.  
  3287.     d = (int)blows_table[str_index][dex_index];
  3288.     
  3289.     if (py.misc.pclass != 0)    /* Non-warrior attack penalty */
  3290.         if (d > 5)
  3291.         d = 5;
  3292.     if (py.misc.pclass == 1)
  3293.         if (d > 4)
  3294.         d = 4;
  3295.  
  3296.     d += s;
  3297.     return ((d < 1) ? 1 : d);
  3298.     }
  3299. }
  3300.  
  3301.  
  3302. /* Special damage due to magical abilities of object    -RAK-     */
  3303. int 
  3304. tot_dam(i_ptr, tdam, monster)
  3305. register inven_type *i_ptr;
  3306. register int         tdam;
  3307. int                  monster;
  3308. {
  3309.     register creature_type *m_ptr;
  3310.     register recall_type   *r_ptr;
  3311.     int                     reduced = FALSE;
  3312.     /* don't resist more than one thing.... -CWS */
  3313.  
  3314.     if ((((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) ||
  3315.      ((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) ||
  3316.      (i_ptr->tval == TV_FLASK))) {
  3317.     m_ptr = &c_list[monster];
  3318.     r_ptr = &c_recall[monster];
  3319.     /* Mjollnir? :-> */
  3320.     if (!(m_ptr->cdefense & IM_LIGHTNING) && (i_ptr->flags2 & TR_LIGHTNING)) {
  3321.         tdam *= 5;
  3322.     }
  3323.     /* Execute Dragon */
  3324.     else if ((m_ptr->cdefense & DRAGON) && (i_ptr->flags & TR_SLAY_X_DRAGON)) {
  3325.         tdam *= 5;
  3326.         r_ptr->r_cdefense |= DRAGON;
  3327.     }
  3328.     /* Slay Dragon  */
  3329.     else if ((m_ptr->cdefense & DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON)) {
  3330.         tdam *= 3;
  3331.         r_ptr->r_cdefense |= DRAGON;
  3332.     }
  3333.     /* Slay Undead  */
  3334.     else if ((m_ptr->cdefense & UNDEAD) && (i_ptr->flags & TR_SLAY_UNDEAD)) {
  3335.         tdam *= 3;
  3336.         r_ptr->r_cdefense |= UNDEAD;
  3337.     }
  3338.     /* Slay ORC     */
  3339.     else if ((m_ptr->cdefense & ORC) && (i_ptr->flags2 & TR_SLAY_ORC)) {
  3340.         tdam *= 3;
  3341.         r_ptr->r_cdefense |= ORC;
  3342.     }
  3343.     /* Slay TROLL     */
  3344.     else if ((m_ptr->cdefense & TROLL) && (i_ptr->flags2 & TR_SLAY_TROLL)) {
  3345.         tdam *= 3;
  3346.         r_ptr->r_cdefense |= TROLL;
  3347.     }
  3348.     /* Slay GIANT     */
  3349.     else if ((m_ptr->cdefense & GIANT) && (i_ptr->flags2 & TR_SLAY_GIANT)) {
  3350.         tdam *= 3;
  3351.         r_ptr->r_cdefense |= GIANT;
  3352.     }
  3353.     /* Slay DEMON     */
  3354.     else if ((m_ptr->cdefense & DEMON) && (i_ptr->flags2 & TR_SLAY_DEMON)) {
  3355.         tdam *= 3;
  3356.         r_ptr->r_cdefense |= DEMON;
  3357.     }
  3358.     /* Frost           */
  3359.     else if ((!(m_ptr->cdefense & IM_FROST))
  3360.          && (i_ptr->flags & TR_FROST_BRAND)) {
  3361.         tdam *= 3;
  3362.     }
  3363.     /* Fire          */
  3364.     else if ((!(m_ptr->cdefense & IM_FIRE))
  3365.          && (i_ptr->flags & TR_FLAME_TONGUE)) {
  3366.         tdam *= 3;
  3367.     }
  3368.     /* Slay Evil     */
  3369.     else if ((m_ptr->cdefense & EVIL) && (i_ptr->flags & TR_SLAY_EVIL)) {
  3370.         tdam *= 2;
  3371.         r_ptr->r_cdefense |= EVIL;
  3372.     }
  3373.     /* Slay Animal  */
  3374.     else if ((m_ptr->cdefense & ANIMAL) && (i_ptr->flags & TR_SLAY_ANIMAL)) {
  3375.         tdam *= 2;
  3376.         r_ptr->r_cdefense |= ANIMAL;
  3377.     }
  3378.                 /* let's do the resistances */
  3379.     if (((m_ptr->cdefense & IM_FROST)) && (i_ptr->flags & TR_FROST_BRAND)) {
  3380.         r_ptr->r_cdefense |= IM_FROST;
  3381.         tdam = (tdam * 3) / 4;
  3382.         reduced = TRUE;
  3383.     }
  3384.     if (((m_ptr->cdefense & IM_FIRE)) && (i_ptr->flags & TR_FLAME_TONGUE)) {
  3385.         r_ptr->r_cdefense |= IM_FIRE;
  3386.         if (!reduced) {
  3387.         tdam = (tdam * 3) / 4;
  3388.         reduced = TRUE;
  3389.         }
  3390.     }
  3391.     if (((m_ptr->cdefense & IM_LIGHTNING)) && (i_ptr->flags2 & TR_LIGHTNING)) {
  3392.         r_ptr->r_cdefense |= IM_LIGHTNING;
  3393.         if (!reduced) {
  3394.         tdam = (tdam * 3) / 4;
  3395.         reduced = TRUE;
  3396.         }
  3397.     }
  3398.     if ((i_ptr->flags2 & TR_IMPACT) && (tdam > 50))
  3399.         earthquake();
  3400.     }
  3401.     return (tdam);
  3402. }
  3403.  
  3404.  
  3405. /* Critical hits, Nasty way to die.            -RAK-     */
  3406. int 
  3407. critical_blow(weight, plus, dam, attack_type)
  3408. register int weight, plus, dam;
  3409. int          attack_type;
  3410. {
  3411.     register int critical;
  3412.  
  3413.     critical = dam;
  3414. /* Weight of weapon, plusses to hit, and character level all */
  3415. /* contribute to the chance of a critical                 */
  3416.     if (randint(5000) <= (int)(weight + 5 * plus
  3417.                  + (class_level_adj[py.misc.pclass][attack_type]
  3418.                 * py.misc.lev))) {
  3419.     weight += randint(650);
  3420.     if (weight < 400) {
  3421.         critical = 2 * dam + 5;
  3422.         msg_print("It was a good hit!");
  3423.     } else if (weight < 700) {
  3424.         critical = 2 * dam + 10;
  3425.         msg_print("It was an excellent hit!");
  3426.     } else if (weight < 900) {
  3427.         critical = 3 * dam + 15;
  3428.         msg_print("It was a superb hit!");
  3429.     } else if (weight < 1300) {
  3430.         critical = 3 * dam + 20;
  3431.         msg_print("It was a *GREAT* hit!");
  3432.     } else {
  3433.         critical = ((7 * dam) / 2) + 25;
  3434.         msg_print("It was a *SUPERB* hit!");
  3435.     }
  3436.     }
  3437.     return (critical);
  3438. }
  3439.  
  3440.  
  3441. /* Given direction "dir", returns new row, column location -RAK- */
  3442. /* targeting code stolen from Morgul -CFT */
  3443. /* 'dir=0' moves toward target                    CDW  */
  3444. int 
  3445. mmove(dir, y, x)
  3446. int                 dir;
  3447. register int       *y, *x;
  3448. {
  3449.     register int new_row = 0, new_col = 0;
  3450.     int          boolflag;
  3451.  
  3452.     switch (dir) {
  3453. #ifdef TARGET
  3454.       case 0:            /* targetting code stolen from Morgul -CFT */
  3455.     new_row = *y;
  3456.     new_col = *x;
  3457.     mmove2(&new_row, &new_col,
  3458.            char_row, char_col,
  3459.            target_row, target_col);
  3460.     break;
  3461. #endif /* TARGET */
  3462.       case 1:
  3463.     new_row = *y + 1;
  3464.     new_col = *x - 1;
  3465.     break;
  3466.       case 2:
  3467.     new_row = *y + 1;
  3468.     new_col = *x;
  3469.     break;
  3470.       case 3:
  3471.     new_row = *y + 1;
  3472.     new_col = *x + 1;
  3473.     break;
  3474.       case 4:
  3475.     new_row = *y;
  3476.     new_col = *x - 1;
  3477.     break;
  3478.       case 5:
  3479.     new_row = *y;
  3480.     new_col = *x;
  3481.     break;
  3482.       case 6:
  3483.     new_row = *y;
  3484.     new_col = *x + 1;
  3485.     break;
  3486.       case 7:
  3487.     new_row = *y - 1;
  3488.     new_col = *x - 1;
  3489.     break;
  3490.       case 8:
  3491.     new_row = *y - 1;
  3492.     new_col = *x;
  3493.     break;
  3494.       case 9:
  3495.     new_row = *y - 1;
  3496.     new_col = *x + 1;
  3497.     break;
  3498.     }
  3499.     boolflag = FALSE;
  3500.     if ((new_row >= 0) && (new_row < cur_height)
  3501.     && (new_col >= 0) && (new_col < cur_width)) {
  3502.     *y = new_row;
  3503.     *x = new_col;
  3504.     boolflag = TRUE;
  3505.     }
  3506.     return (boolflag);
  3507. }
  3508.  
  3509.  
  3510. /* Saving throws for player character.        -RAK-     */
  3511. int 
  3512. player_saves()
  3513. {
  3514.     /* MPW C couldn't handle the expression, so split it into two parts */
  3515.     int16 temp = class_level_adj[py.misc.pclass][CLA_SAVE];
  3516.  
  3517.     if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
  3518.              + (temp * py.misc.lev / 3)))
  3519.     return (TRUE);
  3520.     else
  3521.     return (FALSE);
  3522. }
  3523.  
  3524.  
  3525. /* Finds range of item in inventory list        -RAK-     */
  3526. int 
  3527. find_range(item1, item2, j, k)
  3528. int           item1, item2;
  3529. register int *j, *k;
  3530. {
  3531.     register int         i;
  3532.     register inven_type *i_ptr;
  3533.     int                  flag;
  3534.  
  3535.     i = 0;
  3536.     *j = (-1);
  3537.     *k = (-1);
  3538.     flag = FALSE;
  3539.     i_ptr = &inventory[0];
  3540.     while (i < inven_ctr) {
  3541.     if (!flag) {
  3542.         if ((i_ptr->tval == item1) || (i_ptr->tval == item2)) {
  3543.         flag = TRUE;
  3544.         *j = i;
  3545.         }
  3546.     } else {
  3547.         if ((i_ptr->tval != item1) && (i_ptr->tval != item2)) {
  3548.         *k = i - 1;
  3549.         break;
  3550.         }
  3551.     }
  3552.     i++;
  3553.     i_ptr++;
  3554.     }
  3555.     if (flag && (*k == -1))
  3556.     *k = inven_ctr - 1;
  3557.     return (flag);
  3558. }
  3559.  
  3560.  
  3561. /* Teleport the player to a new location        -RAK-     */
  3562. void 
  3563. teleport(dis)
  3564. int dis;
  3565. {
  3566.     register int y, x, count;
  3567.  
  3568.     do {
  3569.     count = 0;
  3570.     do {
  3571.         count += 1;
  3572.         y = randint(cur_height) - 1;
  3573.         x = randint(cur_width) - 1;
  3574.         while (distance(y, x, char_row, char_col) > dis) {
  3575.         y += ((char_row - y) / 2);
  3576.         x += ((char_col - x) / 2);
  3577.         }
  3578.     }
  3579.     while (((cave[y][x].fval >= MIN_CLOSED_SPACE) ||
  3580.         (cave[y][x].cptr >= 2) ||
  3581.         (t_list[cave[y][x].tptr].index == OBJ_OPEN_DOOR) ||
  3582.         (cave[y][x].fval == NT_DARK_FLOOR) ||
  3583.         (cave[y][x].fval == NT_LIGHT_FLOOR)) && count < 1000);
  3584.  
  3585.     dis *= 2;
  3586.     } while (count == 1000);
  3587.  
  3588.     move_rec(char_row, char_col, y, x);
  3589.  
  3590.     /* unlight area teleported from */
  3591.     darken_player(char_row, char_col);
  3592.  
  3593.     char_row = y;
  3594.     char_col = x;
  3595.     check_view();
  3596.     creatures(FALSE);
  3597.     teleport_flag = FALSE;
  3598. }
  3599.  
  3600.  
  3601. /* Add a comment to an object description.        -CJS- */
  3602. void 
  3603. scribe_object()
  3604. {
  3605.     int   item_val, j;
  3606.     vtype out_val, tmp_str;
  3607.  
  3608.     if (inven_ctr > 0 || equip_ctr > 0) {
  3609.     if (get_item(&item_val, "Which one? ", 0, INVEN_ARRAY_SIZE, 0)) {
  3610.         objdes(tmp_str, &inventory[item_val], TRUE);
  3611.         (void)sprintf(out_val, "Inscribing %s.", tmp_str);
  3612.         msg_print(out_val);
  3613.         if (inventory[item_val].inscrip[0] != '\0')
  3614.         (void)sprintf(out_val, "Replace \"%s\" with the inscription: ",
  3615.                   inventory[item_val].inscrip);
  3616.         else
  3617.         (void)strcpy(out_val, "Inscription: ");
  3618.         j = 78 - strlen(tmp_str);
  3619.         if (j > 12)
  3620.         j = 12;
  3621.         prt(out_val, 0, 0);
  3622.         if (get_string(out_val, 0, strlen(out_val), j))
  3623.         inscribe(&inventory[item_val], out_val);
  3624.     }
  3625.     } else
  3626.     msg_print("You are not carrying anything to inscribe.");
  3627. }
  3628.  
  3629. /* Append an additional comment to an object description.    -CJS- */
  3630. void 
  3631. add_inscribe(i_ptr, type)
  3632. inven_type *i_ptr;
  3633. int         type;
  3634. {
  3635.     i_ptr->ident |= (int8u) type;
  3636. }
  3637.  
  3638. /* Replace any existing comment in an object description with a new one. CJS */
  3639. void 
  3640. inscribe(i_ptr, str)
  3641. inven_type *i_ptr;
  3642. const char *str;
  3643. {
  3644.     (void)strcpy(i_ptr->inscrip, str);
  3645. }
  3646.  
  3647.  
  3648. /* We need to reset the view of things.            -CJS- */
  3649. void 
  3650. check_view()
  3651. {
  3652.     register int        i, j;
  3653.     register cave_type *c_ptr, *d_ptr;
  3654.  
  3655.     c_ptr = &cave[char_row][char_col];
  3656. /* Check for new panel           */
  3657.     if (get_panel(char_row, char_col, FALSE))
  3658.     prt_map();
  3659. /* Move the light source           */
  3660.     move_light(char_row, char_col, char_row, char_col);
  3661. /* A room of light should be lit.     */
  3662.     if (c_ptr->fval == LIGHT_FLOOR) {
  3663.     if ((py.flags.blind < 1) && !c_ptr->pl)
  3664.         light_room(char_row, char_col);
  3665.     }
  3666. /* In doorway of light-room?           */
  3667.     else if (c_ptr->lr && (py.flags.blind < 1)) {
  3668.     for (i = (char_row - 1); i <= (char_row + 1); i++)
  3669.         for (j = (char_col - 1); j <= (char_col + 1); j++) {
  3670.         d_ptr = &cave[i][j];
  3671.         if ((d_ptr->fval == LIGHT_FLOOR) && !d_ptr->pl)
  3672.             light_room(i, j);
  3673.         }
  3674.     }
  3675. }
  3676.